Esempio n. 1
0
 /**
  * Import users
  *
  * This function is used to import users from the given CSV
  * file.
  * <br/>Example:
  * <code>
  * $file = new EfrontFile(/var/www/efront/upload/admin/temp/users.csv);
  * EfrontSystem :: importUsers($file);
  * </code>
  *
  * @param mixed $file The CVS file with the users, either an EfrontFile object or the full path to the file
  * @param boolean $replaceUsers Whether to replace existing users having the same name as the ones imported
  * @return array The imported users in an array of EfrontUser objects
  * @since 3.5.0
  * @access public
  */
 public static function importUsers($file, $replaceUsers = false)
 {
     if (!$file instanceof EfrontFile) {
         $file = new EfrontFile($file);
     }
     $usersTable = eF_getTableData("users", "*", "");
     $tableFields = array_keys($usersTable[0]);
     // Get user types to check if they exist
     $userTypesTable = eF_getTableData("user_types", "*", "");
     // Set the userTypesTable to find in O(1) the existence or not of a user-type according to its name
     foreach ($userTypesTable as $key => $userType) {
         $userTypesTable[$userType['name']] = $userType;
     }
     // If we work on the enterprise version we need to distinguish between users and module_hcd_employees tables fields
     //$userFields = array('login', 'password','email','languages_NAME','name','surname','active','comments','user_type','timestamp','avatar','pending','user_types_ID');
     $userFields = eF_getTableFields('users');
     $existingUsers = eF_getTableDataFlat("users", "login");
     $fileContents = file_get_contents($file['path']);
     $fileContents = explode("\n", trim($fileContents));
     $separator = ";";
     //$fields       = explode($separator, trim($fileContents[0]));
     $fields = str_getcsv(trim($fileContents[0]), $separator);
     if (sizeof($fields) == 1) {
         $separator = ",";
         //$fields    = explode($separator, $fileContents[0]);
         $fields = str_getcsv(trim($fileContents[0]), $separator);
         if (sizeof($fields) == 1) {
             throw new Exception(_UNKNOWNSEPARATOR, EfrontSystemException::ILLEGAL_CSV);
         }
     }
     foreach ($fields as $key => $value) {
         if (empty($value)) {
             $unused = $key;
             unset($fields[$key]);
         }
     }
     $inserted = 0;
     $matched = array_intersect($fields, $tableFields);
     $newUsers = array();
     $messages = array();
     // The check here is removed to offer interoperability between enterprise and educational versions
     // throw new Exception (_PLEASECHECKYOURCSVFILEFORMAT, EfrontSystemException::ILLEGAL_CSV);
     for ($i = 1; $i < sizeof($fileContents); $i++) {
         //$csvUser = explode($separator, $fileContents[$i]);
         $csvUser = str_getcsv($fileContents[$i], $separator);
         unset($csvUser[$unused]);
         if (sizeof($csvUser) != sizeof($fields)) {
             throw new Exception(_PLEASECHECKYOURCSVFILEFORMAT . ': ' . _NUMBEROFFIELDSMUSTBE . ' ' . sizeof($fields) . ' ' . _BUTFOUND . ' ' . sizeof($csvUser), EfrontSystemException::ILLEGAL_CSV);
         }
         $csvUser = array_combine($fields, $csvUser);
         array_walk($csvUser, create_function('&$v, $k', '$v=trim($v);'));
         if (in_array($csvUser['login'], $existingUsers['login']) && $replaceUsers) {
             $existingUser = EfrontUserFactory::factory($csvUser['login']);
             $existingUser->delete();
         }
         if (!in_array($csvUser['login'], $existingUsers['login']) || $replaceUsers) {
             if (!isset($csvUser['password']) || !$csvUser['password']) {
                 $csvUser['password'] = $csvUser['login'];
             }
             // Check the user-type existence by name
             if ($csvUser['user_type_name'] != "" && isset($userTypesTable[$csvUser['user_type_name']])) {
                 // If there is a mismatch between the imported custom type basic type and the current basic type
                 // then set no custom type
                 if ($userTypesTable[$csvUser['user_type_name']]['basic_user_type'] != $csvUser['user_type']) {
                     $csvUser['user_types_ID'] = 0;
                 } else {
                     $csvUser['user_types_ID'] = $userTypesTable[$csvUser['user_type_name']]['id'];
                 }
             } else {
                 $csvUser['user_types_ID'] = 0;
             }
             unset($csvUser['user_type_name']);
             if (!$csvUser['user_type']) {
                 $csvUser['user_type'] = 'student';
             }
             //If user type is not valid, don't insert that user
             if ($csvUser['user_type'] != "administrator" && $csvUser['user_type'] != "professor" && $csvUser['user_type'] != "student") {
                 $messages[] = '&quot;' . $csvUser['login'] . '&quot;: ' . _INVALIDUSERTYPE;
                 unset($csvUser);
                 continue;
             }
             // If we are not in enterprise version then $csvEmployeeProperties is used as a buffer
             // This is done to enable enterprise <-> Enteprise, educational <-> educational, enterprise <-> educational imports/exports
             $csvEmployeeProperties = $csvUser;
             if (G_VERSIONTYPE == 'enterprise') {
                 #cpp#ifdef ENTERPRISE
                 // Copy all fields and remove the user ones -> leaving only employee related fields
                 $csvEmployeeProperties['users_login'] = $csvUser['login'];
             }
             #cpp#endif
             // Delete and recreate $csvUser to keep only the fields in userFields
             unset($csvUser);
             foreach ($userFields as $field) {
                 if (isset($csvEmployeeProperties[$field])) {
                     $csvUser[$field] = $csvEmployeeProperties[$field];
                     if (G_VERSIONTYPE == 'enterprise') {
                         #cpp#ifdef ENTERPRISE
                         unset($csvEmployeeProperties[$field]);
                     }
                     #cpp#endif
                 }
             }
             try {
                 if (G_VERSIONTYPE == 'enterprise') {
                     #cpp#ifdef ENTERPRISE
                     $user = EfrontUser::createUser($csvUser);
                     if (isset($csvEmployeeProperties['branch_name'])) {
                         $result = eF_getTableData("module_hcd_branch", "branch_ID", "name='" . $csvEmployeeProperties['branch_name'] . "'");
                         if ($result[0]['branch_ID']) {
                             $branchId = $result[0]['branch_ID'];
                         }
                         unset($csvEmployeeProperties['branch_name']);
                     }
                     if (isset($csvEmployeeProperties['job_name'])) {
                         $result = eF_getTableData("module_hcd_job_description", "job_description_ID", "description='" . $csvEmployeeProperties['job_name'] . "'");
                         if ($result[0]['job_description_ID']) {
                             $jobId = $result[0]['job_description_ID'];
                         }
                         unset($csvEmployeeProperties['job_name']);
                     }
                     if (isset($csvEmployeeProperties['job_role'])) {
                         $csvEmployeeProperties['job_role'] ? $jobRole = 1 : ($jobRole = 0);
                         unset($csvEmployeeProperties['job_role']);
                     }
                     $user->aspects['hcd'] = EfrontHcdUser::createUser($csvEmployeeProperties);
                     if (isset($branchId) && isset($jobId) && isset($jobRole)) {
                         $user->aspects['hcd']->addJob($user, $jobId, $branchId, $jobRole);
                     }
                     $newUsers[] = $user;
                 } else {
                     #cpp#else
                     $newUsers[] = EfrontUser::createUser($csvUser);
                 }
                 #cpp#endif
             } catch (Exception $e) {
                 $messages[] = '&quot;' . $csvUser['login'] . '&quot;: ' . $e->getMessage() . ' (' . $e->getCode() . ')';
             }
         }
     }
     return array($newUsers, $messages);
 }
Esempio n. 2
0
 /**
  * Construct content tree structure
  *
  * Creates a tree-like representation of the content, using arrays as EfrontUnit,
  * a class that extends ArrayObject.
  * Each unit is represented as an array with the appropriate fields
  * (id, name, timestamp etc). If the unit has children units, then
  * these are subarrays of the current unit array. All keys correspond
  * to unit ids.
  * If, for some reason, there are units with invalid succession data,
  * (parent or previous content ids), these are appended at the end of
  * the content tree.
  * <br/>Example:
  * <code>
  * $content = new EfrontContentTree(4);                                 //Initialize content tree for lesson with id 4
  * //Do some nasty stuff with content tree
  * $content -> reset();                                                 //Reset content tree to its original state
  * </code>
  *
  * @since 3.5.0
  * @access public
  */
 public function reset()
 {
     if ($this->data) {
         $result = eF_getTableData("content", "*, data != '' as has_data", "lessons_ID = '" . $this->lessonId . "'");
     } else {
         $fields = eF_getTableFields("content");
         unset($fields[array_search('data', $fields)]);
         $result = eF_getTableData("content", implode(",", $fields) . ", data != '' as has_data", "lessons_ID = '" . $this->lessonId . "'");
     }
     if (sizeof($result) == 0) {
         $this->tree = new RecursiveArrayIterator(array());
         return;
     }
     $scorm2004Units = array();
     $units = array();
     foreach ($result as $unit) {
         $units[$unit['id']] = $unit;
         if (G_VERSIONTYPE != 'community') {
             #cpp#ifndef COMMUNITY
             if (G_VERSIONTYPE != 'standard') {
                 #cpp#ifndef STANDARD
                 if (in_array($unit['scorm_version'], EfrontContentTreeSCORM::$scorm2004Versions)) {
                     $scorm2004Units[] = $unit['id'];
                 }
             }
             #cpp#endif
         }
         #cpp#endif
     }
     if (!empty($scorm2004Units)) {
         $units = $this->convertUnitsTo2004($units, $scorm2004Units);
     }
     //$units   = eF_getTableData("content", "id,name,parent_content_ID,lessons_ID,timestamp,ctg_type,active,previous_content_ID", "lessons_ID = '".$this -> lessonId."'");
     $rejected = array();
     foreach ($units as $node) {
         //Assign previous content ids as keys to the previousNodes array, which will be used for sorting afterwards
         if (!$this->data) {
             $node['has_data'] ? $node['data'] = 'efront#special#text' : ($node['data'] = '');
             //Eliminate with 'efront#special#text' data for units that don't have any content, and set an empty space ' ' for units that have content. This is done so that the toHTML can handle differently the ones from the others. The efront#special#text is checked by persist() in order to leave data unchanged in case we are updating
         }
         $node = new EfrontUnit($node);
         //We convert arrays to array objects, which is best for manipulating data through iterators
         if (!isset($previousNodes[$node['previous_content_ID']])) {
             $previousNodes[$node['previous_content_ID']] = $node;
         } else {
             $rejected[$node['id']] = $node;
             //$rejected holds cut off units, which do not have a valid previous_content_ID
         }
     }
     $node = 0;
     $count = 0;
     $nodes = array();
     //$count is used to prevent infinite loops
     while (sizeof($previousNodes) > 0 && isset($previousNodes[$node]) && $count++ < 10000) {
         //Order the nodes array according to previous_content_ID information. if $previousNodes[$node] is not set, it means that there are illegal previous content id entries in the array (for example, a unit reports as previous a non-existent unit). In this case, all the remaining units in the $previousNodes array are rejected
         $nodes[$previousNodes[$node]['id']] = $previousNodes[$node];
         //Assign the previous node to be the array key
         $newNode = $previousNodes[$node]['id'];
         unset($previousNodes[$node]);
         $node = $newNode;
     }
     if (sizeof($previousNodes) > 0) {
         //If $previousNodes is not empty, it means there are invalid (orphan) units in the array, so append them to the $rejected list
         foreach ($previousNodes as $value) {
             $rejected[$value['id']] = $value;
         }
     }
     $tree = $nodes;
     $count = 0;
     //$count is used to prevent infinite loops
     while (sizeof($tree) > 1 && $count++ < 50000) {
         //We will merge all branches under the main tree branch, the 0 node, so its size will become 1
         foreach ($nodes as $key => $value) {
             if ($value['parent_content_ID'] == 0 || in_array($value['parent_content_ID'], array_keys($nodes))) {
                 //If the unit parent is in the $nodes array keys - which are the unit ids- or it is 0, then it is  valid
                 $parentNodes[$value['parent_content_ID']][] = $value;
                 //Find which nodes have children and assign them to $parentNodes
                 $tree[$value['parent_content_ID']][$value['id']] = array();
                 //We create the "slots" where the node's children will be inserted. This way, the ordering will not be lost
             } else {
                 $rejected = $rejected + array($value['id'] => $value);
                 //Append units with invalid parents to $rejected list
                 unset($nodes[$key]);
                 //Remove the invalid unit from the units array, as well as from the parentUnits, in case a n entry for it was created earlier
                 unset($parentNodes[$value['parent_content_ID']]);
             }
         }
         if (isset($parentNodes)) {
             //If the unit was rejected, there won't be a $parentNodes array
             $leafNodes = array_diff(array_keys($nodes), array_keys($parentNodes));
             //Now, it's easy to see which nodes are leaf nodes, just by subtracting $parentNodes from the whole set
             foreach ($leafNodes as $leaf) {
                 $parent_id = $nodes[$leaf]['parent_content_ID'];
                 //Get the leaf's parent
                 $tree[$parent_id][$leaf] = $tree[$leaf];
                 //Append the leaf to its parent's tree branch
                 unset($tree[$leaf]);
                 //Remove the leaf from the main tree branch
                 unset($nodes[$leaf]);
                 //Remove the leaf from the nodes set
             }
             unset($parentNodes);
             //Reset $parentNodes; new ones will be calculated at the next loop
         }
     }
     if (sizeof($tree) > 0 && !isset($tree[0])) {
         //This is a special case, where only one node exists in the tree
         $tree = array($tree);
     }
     isset($tree[0]) ? $tree = $tree[0] : ($tree = array());
     if (sizeof($rejected) > 0) {
         //Append rejected nodes to the end of the tree array, updating their parent/previous information
         foreach (new EfrontNodeFilterIterator(new RecursiveIteratorIterator(new RecursiveArrayIterator($tree), RecursiveIteratorIterator::SELF_FIRST)) as $lastUnit) {
         }
         //Advance to the last tree node
         isset($lastUnit) ? $previousId = $lastUnit['id'] : ($previousId = 0);
         //There is a chance that no normal units exist in the tree. In this case, there will be no $lastUnit
         foreach ($rejected as $id => $node) {
             //Update broken nodes
             $node['parent_content_ID'] = 0;
             $node['previous_content_ID'] = $previousId;
             $node->persist();
             //Persist changes to the database
             $tree[$id] = $node;
             $previousId = $id;
         }
     }
     $this->tree = new RecursiveArrayIterator($tree);
     //Create arrays for assigning the immediate children and the parents of each unit. These will come especially handy for SCORM 2004 calculations
     $this->immediateDescendants = array();
     $this->nodeParents = array();
     foreach (new EfrontNodeFilterIterator(new RecursiveIteratorIterator(new RecursiveArrayIterator($tree), RecursiveIteratorIterator::SELF_FIRST)) as $key => $value) {
         foreach (array_keys((array) $value) as $member) {
             !is_numeric($member) or $this->immediateDescendants[$key][] = $member;
         }
         if (isset($this->nodeParents[$value['parent_content_ID']]) && $this->nodeParents[$value['parent_content_ID']]) {
             $this->nodeParents[$key] = array_merge(array($value['parent_content_ID']), $this->nodeParents[$value['parent_content_ID']]);
         } else {
             $this->nodeParents[$key] = array($value['parent_content_ID']);
         }
     }
     //pr($this -> nodeParents);
     //pr($this -> immediateDescendants);
 }