/PluggableAuth/includes/PHPDS_importUser.class.php
PHP | 783 lines | 387 code | 86 blank | 310 comment | 57 complexity | d8b9223e92517a220f258fc18cd1ad8f MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, LGPL-2.1, LGPL-3.0
- <?php
-
- /**
- <<<<<<< TREE
- * PHPDevShell is a RAD Framework aimed at developing administrative applications.
- *
- * @package PHPDevShell
- * @link http://www.phpdevshell.org
- * @copyright Copyright (C) 2007 Jason Schoeman, All rights reserved.
- * @license GNU/LGPL, see readme/licensed_under_lgpl or http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
- *
- * Copyright notice: See readme/notice
- * By using PHPDevShell you agree to notice and license, if you dont agree to this notice/license you are not allowed to use PHPDevShell.
- *
- */
-
- require_once dirname(__FILE__).'/../models/PHPDS_importUser.query.php';
-
- /**
- =======
- >>>>>>> MERGE-SOURCE
- * A class representing a user in PHPDevShell.
- *
- * Can be used to examine / modify an existing user, or create / import a new user
- *
- * @date 20091125
- * @version 1.0.1
- * @author Greg
- */
- class PHPDS_importUser extends PHPDS_user
- {
- //for flexibily all user data are stored in an array
- protected $data = array(); // main table
- protected $data_ex = array(); // overflow table
- protected $ready = false; // if the user object is actually ready to be used (i.e. fields are valid)
- protected $userid = false; // if the user is know to exist in the database, here is his user ID
- protected $dirty = false; // if the user data in memory are different from the user data in the database
- protected $tokenid = false; // token to authorize the user
- protected $overflowtable = false; // table to hold extended data
- protected $primary_group = null;
- protected $primary_role = null;
- protected $extra_groups = array(); // associative array: [groupID] = true
- protected $extra_roles = array(); // associative array: [roleID] = true
- protected $lookupQuery; // PHPDS_FindUsersQuery
- /**
- * Constructor
- *
- * Initialize a User object and optionnaly tries to load a given user's data
- *
- * @version 1.0.2
- * @author greg
- * @date 20100921 (v1.0.2) (greg) moved to new style constructor, removing the $dependancy parameter
- * @date 20100412 (v1.0.1) (greg) removed tokenid
- * @date 20091126 created
- * @return the user obejct
- */
-
- public function construct($username = null)
- {
- $this->init();
-
- if ($username) $this->load($username);
-
- return $this;
- }
-
- /**
- * Magic getter
- * Used to directly access (read only) the user's data
- *
- * @version 1.0
- * @date 20091126 created
- * @see current/includes/PHPDS_dependant#__get($name)
- */
- public function __get($field)
- {
- if (isset($this->data[$field])) return $this->data[$field];
- if (isset($this->data_ex[$field])) return $this->data_ex[$field];
- return parent::__get($field);
- }
-
- /**
- * Initialize the object with some default values
- *
- * For all load/import methods, this is what the new data will be merge onto
- *
- * @version 1.0
- * @date 20091126 created
- * @return the user obejct
- */
- public function init()
- {
- $this->data = array();
- $this->data_ex = array();
-
- $this->extra_groups = array();
- $this->extra_roles = array();
-
- $this->ready = false;
- $this->dirty = false;
- $this->userid = false;
-
- // these fields are to be filled
- $this->data['user_id'] = 0;
- $this->data['user_name'] = _('MISSING???');
- $this->data['user_display_name'] = _('MISSING???');
- $this->data['user_email'] = _('MISSING???');
- $this->data['user_password'] = 'password';
-
- $settings = $this->db->getSettings(array('registration_group', 'registration_role'), 'PHPDevShell');
- // these fields have default values
-
- //$this->PHPDS_dependance->copyArray($settings, &$this->data, array('registration_group'));
-
- $this->data['user_group'] = $settings['registration_group'];
- $this->data['user_role'] = $settings['registration_role'];
- $this->data['date_registered'] = $this->configuration['time'];
- $this->data['language'] = $this->configuration['language'];
- if (isset($this->configuration['user_timezone'])) {
- $this->data['user_timezone'] = $this->configuration['user_timezone'];
- $this->data['timezone'] = $this->configuration['user_timezone'];
- } else {
- $this->data['user_timezone'] = '';
- $this->data['timezone'] = '';
- }
- $this->data['region'] = $this->configuration['region'];
-
- return $this;
- }
-
- /**
- * Set/Get the user ID
- *
- * @version 1.0
- * @date 20091126 created
- * @author greg
- * @param $userID (optional)
- * @return integer the user ID
- */
- protected function ID($userID = null)
- {
- $ID = intval($userID);
- if ($ID > 0) {
- $this->userid = $ID;
- $this->data['user_id'] = $ID;
- }
- return $this->userid;
- }
-
- /**
- * Return an associative array with all user data
- *
- * @version 1.0
- * @author greg
- * @return array
- */
- public function data()
- {
- return array_merge($this->data, $this->data_ex);
- }
-
- /**
- *
- * @return PHPDS_query
- */
- protected function lookupQuery()
- {
- if (empty($this->lookupQuery)) {
- $this->lookupQuery = $this->db->makeQuery('PHPDS_FindUserQuery');
- }
- return $this->lookupQuery;
- }
-
- /**
- * Lookup a name in the database, optionaly loading the data
- *
- * Note: if the data is loaded, the object is reset before importing. If the data is not loaded, the object stays untouched
- *
- * @version 1.0
- * @date 20091126 created
- * @author greg
- * @param $username (optional) "user_name" to lookup (if empty, taken from the user's data)
- * @param $load (optional, default is not to load) boolean, do we load the data into the object
- * @return integer the user ID (or false if not found)
- */
- public function lookup($username = null, $load = false)
- {
- $ID = false;
- $exists = false;
-
- $existing_user = $this->lookupQuery()->invoke($username);
- $exists = !empty($existing_user['user_id']);
-
- if ($exists) $ID = intval($existing_user['user_id']);
-
- if ($exists && $load) {
- $this->init();
- $this->ID($existing_user['user_id']);
-
- $this->importArray($existing_user);
-
- $this->primary_group = $existing_user['user_group'];
- $this->primary_role = $existing_user['user_role'];
-
- $groups = $this->db->invokeQuery('PHPDS_UserGroupsQuery', $ID);
- if ($groups)
- foreach ($groups as $group)
- $this->addGroup($group['user_group_id']);
-
- $roles = $this->db->invokeQuery('PHPDS_UserRolesQuery', $ID);
- if ($roles)
- foreach ($roles as $role)
- $this->addRole($role['user_role_id']);
-
- $this->ready = true;
- $this->dirty = false;
- }
-
- $this->log('Looking up user "'.$username.'" gave id '.$ID);
- return $ID;
- }
-
- /**
- * Add the user to a group
- *
- * @param $groupID
- * @return unknown_type
- */
- public function addGroup($groupID)
- {
- //array_push($this->extra_groups, intval($groupID));
- $this->extra_groups[intval($groupID)] = true;
- }
-
- public function removeGroup($groupID)
- {
- //array_push($this->extra_groups, intval($groupID));
- unset($this->extra_groups[intval($groupID)]);
- }
-
- /**
- * Return an array of the roles given to the user
- *
- * @return unknown_type
- */
- public function roles()
- {
- return array_keys($this->extra_roles);
- }
-
- /**
- * Return an array of the possible roles for the user
- *
- * @return unknown_type
- */
- public function possibleRoles()
- {
- return $this->db->invokeQuery('PHPDS_RolesQuery');
- }
-
- /**
- * Return an array of the groups the user belongs to
- *
- * @return unknown_type
- */
- public function groups()
- {
- return array_keys($this->extra_groups);
- }
-
- /**
- * Add a role to the user
- *
- * @param $roleID
- * @return unknown_type
- */
- public function addRole($roleID)
- {
- $this->extra_roles[intval($roleID)] = true;
- }
-
- /**
- * Import some data from an array into the object
- *
- * @version 1.0
- * @date 20091126 created
- * @param $import_data associative array of user data
- * @return the user object
- */
- public function importArray(array $import_data)
- {
- $this->ready = false;
-
- foreach ($import_data as $field => $value) {
- if (isset($this->data[$field])) $this->data[$field] = $value;
- else $this->data_ex[$field] = $value;
- }
-
- $this->dirty = true;
- $this->ready = true;
-
- return $this;
- }
-
- public function import(array $import_array)
- {
- $this->ready = false;
-
- foreach ($import_array as $field => $value) {
- $import_data[$field] = $this->valuePrep($field, $value);
- }
-
- $this->importPrep($import_data);
-
- return $this;
-
- }
-
- /**
- * Load a user from the database into the object
- *
- * @version 1.0.1
- * @date 20100412 (v1.0.1) (greg) $username is optional
- * @date 20091126 created
- * @author greg
- * @param $username (optional) "user_name" to lookup (if empty, taken from the user's data)
- * @return integer the user ID (or false if not found)
- */
- public function load($username = null)
- {
- //$this->init();
- if (!$username && isset($this->data['user_name']))
- $username = $this->data['user_name'];
- return $this->lookup($username, true);
- }
-
- /**
- * Save the user object into the database
- *
- * @version 1.1
- * @date 20091126 created
- * @date 20100329 heavily modified
- * @return unknown_type
- */
- public function save()
- {
- if ($this->userid) {
- $existing_user = $this->userid;
- } else {
- if (isset($this->data['user_name'])) {
- $existing_user = $this->lookup(array('user_name' => $this->data['user_name']));
- }
- }
-
- if (empty($existing_user)) $existing_user = 'NULL';
-
-
- $this->log('About to save user id '.$existing_user.' from id '.$this->userid.' / name '.$this->data['user_name']);
- $db = $this->db;
- $user_id = $db->invokeQueryWith('PHPDS_UserReplace', array_merge($this->data, array('existing_user' => $existing_user)));
-
- $this->log('Saving user id '.$user_id);
-
- $db->invokeQuery('PHPDS_UserSetRolesQuery', $user_id, array_keys($this->extra_roles));
- $db->invokeQuery('PHPDS_UserSetGroupsQuery', $user_id, array_keys($this->extra_groups));
-
-
- // TODO
- if (empty($this->overflowtable)) $this->log('No overflow table'); else $this->log('Overflow table is '.$this->overflowtable);
- if (!empty($this->overflowtable) && !empty($this->data_ex)) {
- $overflow_values = false;
- foreach ($this->data_ex as $custom_column => $custom_column_value) {
- $custom_column_value_ = $this->db->protect(str_replace(array("\n", "\r", "\r\n", "\n\r", ",", ";", "'", '"'), '', trim($custom_column_value)));
- $overflow_values .= "$custom_column = '$custom_column_value_',";
- }
- $overflow_values = rtrim($overflow_values, ",");
- $sql = "REPLACE INTO
- {$this->overflowtable}
- SET
- user_id =$user_id, $overflow_values";
- $this->db->newQuery($sql);
- }
-
- $this->ID($user_id);
-
- return $this;
- }
-
- /**
- * Import some data from a csv-like string into the object
- *
- * Note: the object is NOT reset before importing
- *
- * @version 1.0
- * @date 20091126 created
- * @param $line string, the line to import
- * @param $fields array, the (ordered) names of the fields
- * @param $delimiter (optional) string, the csv delimiter
- * @return boolean false if the line doesn't contains as much fields as the $fields array
- */
- public function importCsvLine($line, $fields, $delimiter = "\t")
- {
- $values = explode($delimiter, $line);
- if ($import = array_combine($fields, $values)) {
- $this->import($import);
- return true;
- } else return false;
- }
-
- /**
- * Import several csv-like lines, and save the corresponding user for each line
- *
- * Use $this->import_prep() as a callback for each line
- *
- * @param $lines array of strings, the lines to import
- * @param $fields array, the (ordered) names of the fields
- * @param $delimiter (optional) string, the csv delimiter
- */
- public function importCsv($lines, $fields, $delimiter = "\t")
- {
- foreach ($lines as $line) {
- $this->init();
- $this->importCsvLine($line, $fields, $delimiter);
- if ($this->dirty) $this->save();
- }
- }
-
- /**
- * Import a whole csv-like file into the database
- *
- * Use $this->import_prep() as a callback for each line
- *
- * @param $filename full pathname of the file
- * @param $fields array, the (ordered) names of the fields
- * @param $delimiter (optional) string, the csv delimiter
- * @return unknown_type
- */
- public function importCsvFile($filename, $fields, $delimiter = "\t")
- {
- $content = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES | FILE_TEXT);
- if ($content) return $this->importCsv($content, $fields, $delimiter);
- else return false;
- }
-
- /**
- * This function will be called for each line when importing a file. It's meant to be overriden.
- * Here is a very simple example.
- *
- * No paramaters or return value: everything is done with the object's data
- *
- * Note 1: it's currently only used when importing csv data
- * Note 2: values have already been "prepared"
- */
- public function importPrep($import_data)
- {
- if (($import_data['user_display_name'] == _('MISSING???')) || empty($import_data['user_display_name'])) {
- $import_data['user_display_name'] = $import_data['user_name'];
- }
-
- $this->importArray($import_array);
-
- return $this;
- }
-
- /**
- * This function is called for each value when importing data
- *
- * Its goal is to "prepare" a value before actually importing it
- * This basic implementation just cleans values which are surrounded by double quotes. You are supposed to override it according to your data format
- *
- * @param $field name of the field containing the value
- * @param $value the value to prepare
- * @return mixed, the prepare valued
- */
- public function valuePrep($field, $value)
- {
- $matches = array();
- if (preg_match('/"(.*)"/', $value, $matches)) {
- $value = $matches[1];
- }
- return $value;
- }
-
- /**
- * Dump the object content
- *
- * @return unknown_type
- */
- public function dump()
- {
- print "\nUserID ";
- print_r($this->userid);
- print "\ndirty ";
- print_r($this->dirty);
- print "\nread ";
- print_r($this->ready);
- print "\ndata ";
- print_r($this->data);
- print "\ndata_ex ";
- print_r($this->data_ex);
- print "\nprimary_group ";
- print_r($this->primary_group);
- print "\nextra_groups ";
- print_r(array_keys($this->extra_groups));
- print "\nprimary_role ";
- print_r($this->primary_role);
- print "\nextra_roles ";
- print_r(array_keys($this->extra_roles));
- }
-
- /**
- *
- * @param <type> $name
- * @param <type> $value
- */
- public function __set($name, $value)
- {
- $setter = 'set_' . $name;
- // if there is an explicit method to set this value, let's call it
- if (method_exists($this, $setter)) $this->$setter($value);
- else {
- // no explicit method, so let's try what we can do
- if (isset($this->data[$name])) $this->data[$name] = $value;
- elseif (isset($this->data['user_' . $name]))
- $this->data['user_' . $name] = $value;
- else $this->data_ex[$name] = $value;
- }
- }
-
- /**
- *
- * @param <type> $password
- * @return PHPDS_user
- */
- public function setPassword($password)
- {
- $this->data['user_password'] = md5($password);
- return $this;
- }
-
- /**
- * Lookup all users which are members of any of the current user's groups
- *
- * @return array
- */
- public function siblings()
- {
- return $this->db->invokeQuery('PHPDS_FindUsersQuery');
- }
- }
-
- /**
- * A specific tree for groups handling
- *
- * Usage:
- *
- * $tree = PHPDS_GroupTree::singleton($dependance);
- * echo '<form action="" method="post"><ul id="example">';
- * echo $tree->make_html();
- * echo '<input type="submit" name="submit" value="Send" .>';
- * echo '</ul></form>';
- *
- * Can also be used to find a subgroup for a query:
- *
- $this->where = $tree->user_groups_sql(35); // group 35 and all groups inside it
-
- * Note: it fit in the PHPDS_dependant system
- *
- * @author greg
- *
- */
- class PHPDS_groupTree extends PU_tree
- {
- protected static $instance;
- protected static $dependance;
-
- /** constructor is private to ensure singleton
- *
- * @param $dependance
- * @return irrelevant
- */
- private function __construct($dependance)
- {
- $this->dependance = $dependance;
- }
-
- /**
- * Return the single instance
- *
- * @param PHPDS_dependant $dependance
- * @return PHPDS_GroupTree
- */
- public static function singleton($dependance = null)
- {
- if (!isset(PHPDS_groupTree::$instance)) {
- PHPDS_groupTree::$instance = new PHPDS_groupTree($dependance);
- }
- return PHPDS_groupTree::$instance;
- }
-
- /**
- * Load (only once) all the groups into the tree
- *
- * @return this
- */
- public function load()
- {
- if (empty($this->descendants)) {
- $groups = $this->dependance->db->invokeQuery('PHPDS_AllGroupsQuery');
- if (false == $groups) throw new Exception('Error loading group list');
-
- foreach ($groups as $group) {
- $this->add($group['user_group_id'], $group['parent_group_id'], $group['user_group_name']);
- }
-
- $this->climb();
- }
- return $this;
- }
-
- /**
- * Build an html representation of the groups selector (including INPUTs)
- *
- * Result is something like:
- *
- * <ul>
- * <li>
- * <input type="checkbox" id="group_2" value="2" checked /><label for="group_2">Registered<label>
- * <ul>
- * <li>
- * <input type="checkbox" id="group_6" value="6" checked /><label for="group_6">Clients<label><input type="checkbox" id="group_7" value="7" checked />
- * </li>
- * </ul>
- * </li>
- * </ul>
- *
- * @param integer $branch starting branch (optional, usually 0)
- * @return string html
- */
- public function makeHtml($branch = 0)
- {
- $this->load();
- $cuts = $this->userGroups($branch, true);
- $selected = $cuts;
- return $this->makeHtmlBranch($branch, $cuts, $selected);
- }
-
- /**
- * Sub for the previous function - do not use
- *
- * @param unknown_type $branch
- * @param array $cuts
- * @param array $selected
- * @param unknown_type $propagate
- * @return unknown_type
- */
- public function makeHtmlBranch($branch, array $cuts, array $selected, $propagate = false)
- {
- $html1 = '';
- $html2 = '';
-
- $propagate = $propagate || in_array($branch, $cuts);
- $display = $propagate || (0 == $branch);
-
- if ($display) {
- if ($branch) {
- $id = 'group_' . $branch;
- $html1 .= '<input type="checkbox" id="' . $id . '" ';
- if (isset($this->elements[$branch])) $html1 .= ' value="' . $branch . '"';
- if (in_array($branch, $selected)) $html1 .= ' checked ';
- $html1 .= '/>';
- $html1 .= '<label for="' . $id . '">' . $this->elements[$branch] . '<label>';
- } else {
- $html1 = 'all';
- }
- }
-
- if (!empty($this->descendants[$branch])) {
- foreach ($this->descendants[$branch] as $node)
- $html2 .= $this->makeHtmlBranch($node, $cuts, $selected, $propagate);
- }
-
- // this is tricky, since we may have to display a group nested inside another group which is not displayed
- $html = '';
- if ($html1) $html .= "<li>$html1";
- if ($html1 && $html2) $html .= '<ul>';
- if ($html2) $html .= $html2;
- if ($html1 && $html2) $html .= '</ul>';
- if ($html1) $html .= "</li>\n";
-
- return $html;
- }
-
- /**
- * Returns all groups the user belongs to, which are children of given branch
- *
- * Note: this is used to deal with implicit membership, as we a user of a given group can be considered member of all its subgroups
- *
- * @param unknown_type $branch
- * @param unknown_type $as_array
- * @return unknown_type
- */
- public function userGroups($branch = 0, $as_array = false)
- {
- $this->load();
-
- $descendants = array_unique($this->descendants($branch, true));
- $mygroups = $this->dependance->db->getGroups(false, true);
-
- $groups = array_unique(array_intersect($descendants, $mygroups));
-
- return $as_array ? $groups : implode(',', $groups);
- }
-
- /**
- * Returns a sql snippet based on the previous method
- *
- * @param unknown_type $branch
- * @return unknown_type
- */
- public function userGroupsSql($branch = 0)
- {
- $groups = $this->userGroups($branch, false);
- return $groups ? " user_group_id IN ($groups) OR user_group IN ($groups) " : "false";
- }
-
- /**
- * Find all groups the user belongs to or is a subgroup (a group inside a group the user belongs to)
- *
- * @see stable/phpdevshell/includes/PU_tree#descendants($node, $as_array)
- * @return array of id
- */
- public function descendants($branch = 0, $as_array = true)
- {
- $this->load();
- $descendants = parent::descendants($branch, true);
- $children = $descendants;
- foreach ($descendants as $descendant)
- $children = array_merge($this->descendants($descendant, true), $children);
- $children[] = $branch;
-
- return $as_array ? $children : implode(',', $children);
- }
-
- /**
- * Find all groups hierachy from the given group up to the top
- *
- * @see stable/phpdevshell/includes/PU_tree#ascendants($node, $as_array)
- * @return array of id
- */
- public function ascendants($branch = 0, $as_array = true)
- {
- $this->load();
- $elders = parent::ascendants($branch, true);
- $elders[] = $branch;
- return $as_array ? $elders : implode(',', $elders);
- }
-
- /**
- * Find all groups hierachy from the given group up to the top
- *
- * @see stable/phpdevshell/includes/PU_tree#ascendants($node, $as_array)
- * @return array of id
- */
- public function userGroupNames($branch)
- {
- $nodes = $this->userGroups($branch, true);
- return array_intersect_key($this->elements, array_flip($nodes));
- }
-
- /**
- * Returns an array of names, either the whole tree, or only the groups which IDs are listed in the filter
- *
- * @param array $filter
- * @return array
- */
- public function nodes(array $filter = null)
- {
- $this->load();
- return parent::nodes($filter);
- }
- }
-