<?php if (!defined('PmWiki')) exit();

/*	=== UserAdmin-Profiles ===
 *	Copyright 2010-2015 Eemeli Aro <eemeli@gmail.com>
 *
 *	AuthUser account self-registration and management using profile pages
 *
 *	For more information, please see the online documentation at
 *		http://www.pmwiki.org/wiki/Cookbook/UserAdmin
 *
 *
 *  This script is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

$RecipeInfo['UserAdmin']['Version'] = '2015-05-10';


if (!IsEnabled($EnableAuthorTracking,1)) Abort('$EnableAuthorTracking required for UserAdmin-Profiles');


SDV($AuthUserFunctions['userprofilegroup'], 'AuthUserProfiles');
function AuthUserProfiles($pagename, $id, $pw, $pwlist/*, &$authlist*/) {
	foreach ((array)$pwlist as $pgroup) {
		$pn = MakePageName($pagename, "$pgroup.$id");
		$page = ReadPage($pn, READPAGE_CURRENT);
		if ($page
			&& !empty($page['username'])
			&& ($id == $page['username'])
			&& !empty($page['userpwhash'])
			&& (_crypt($pw, $page['userpwhash']) == $page['userpwhash'])
		) {
			//if (!empty($page['usergroups']) && preg_match_all('/@[^,\s]+/', $page['usergroups'], $m))
			//	foreach ($m[0] as $g) $authlist[$g] = 1;
			return true;
		}
	}
	return false;
}


if (strncmp($action, 'user', 4)) return;


require_once('useradmin-core.php');


class UserAdminProfiles extends UserAdmin {
	var $pgroup = 'Profiles';
	var $username_chars = '[:alnum:]';
	var $username_denied = 'HomePage|SideBar|(Group(Print)?(Attributes|Header|Footer))';

	function ProfilePageName($username) {
		return MakePageName("{$this->pgroup}.{$this->pgroup}", "{$this->pgroup}.$username");
	}

	function ReadUser($username, $readgroup=false) {
		global $PCache;
        #echo "DEBUG: profiles->ReadUser($username): Entering.<br>\n";
		if (!$username) return array();
		$pn = $this->ProfilePageName($username);
		if (empty($PCache[$pn])) {
			$page = ReadPage($pn, READPAGE_CURRENT);
			PCache($pn, $page);
		} else $page = &$PCache[$pn];
        if ($readgroup) $page['usergroups'] = $this->ReadGroups($username);
		$keys = preg_grep('/^user/', array_keys($page));
        # Fall back to SiteAdmin.AuthUser if profile page has problems
        if (!$keys) return parent::ReadUser($username, $readgroup);
		return array_intersect_key($page, array_flip($keys));
	}

	function WriteUser($username, $data, $csum='', $auth='read') {
		global $Now, $EditFunctions, $IsPagePosted;
        parent::WriteUser($username, $data, $csum, $auth); // sets some defaults
		$pn = $this->ProfilePageName($username);
		Lock(2);
			$page = RetrieveAuthPage($pn, $auth, TRUE);
			if (!$page) Abort("?cannot write to $pn"); 
			$new = $page;
			foreach((array)$data as $k => $v) {
				if ($v) $new[$k] = $v;
				else unset($new[$k]);
			}
            if (!@$new['username'])
                $new['username'] = $username;
			$new['csum'] = $csum;
			if ($csum) $new["csum:$Now"] = $csum;
			PCache($pn, $new);
			$k = array_search('SaveAttributes', $EditFunctions);
			if ($k !== FALSE) unset($EditFunctions[$k]);
			UpdatePage($pn, $page, $new);
		Lock(0);
		return $IsPagePosted;
	}

    function ListUsers($pat=NULL)
    {
        $user_list = parent::ListUsers($pat); // get any that are defined in AuthUser page
        #echo "DEBUG: parent user_list=<pre>".print_r($user_list,true)."</pre><br />\n";
        $profile_pages = ListPages($this->pgroup.'.*');
        foreach ($profile_pages as $p) {
            if (($page = RetrieveAuthPage($p, 'read', false)) && @$page['username']) {
                #echo "DEBUG: Got a user! username=$page[username]<br />\n";
                $user_list[] = $page['username'];
            }
        }
        #echo "DEBUG: full user_list=<pre>".print_r($user_list,true)."</pre><br />\n";
		return MatchPageNames(array_unique($user_list), $pat); // this is dup from parent::ListUsers() but difficult to refactor
    }

	function ValidName(&$username) {
		$username = preg_replace("/[^{$this->username_chars}]+/", '', $username);
		if (!$username) return FALSE;

		return !preg_match("/\.({$this->username_denied}|{$this->pgroup})$/", $this->ProfilePageName($username));
	}

	function MakeActivationLink($username, $key) {
		$pn = $this->ProfilePageName($username);
		return FmtPageName('$PageUrl?action=user/unlock&key='.urlencode($key), $pn);
	}

	function UserName($pagename, $opt) {
		$n = parent::UserName($pagename, $opt);
		if ($n) return $n;
		if (!empty($opt['username'])) return FALSE;
		$page = ReadPage($pagename, READPAGE_CURRENT);
		PCache($pagename, $page);
		return empty($page['username']) ? FALSE : $page['username'];
	}

	function Superuser($pagename, $prompt=FALSE) {
		if (!empty($this->input['username'])) $pagename = $this->ProfilePageName($this->input['username']);
		return (boolean)RetrieveAuthPage($pagename, 'attr', $prompt, READPAGE_CURRENT);
	}
}

SDV($UserAdmin, new UserAdminProfiles());