Example #1
0
 /**
  * Loads the publication into the memory and organizes it into a tree.
  */
 public function loadItems()
 {
     /* HOW DOES IT WORK?
     			
     			All the mystery of the chapter tree sorting algorithm lies in the data organization.
     			The main data structure is a 2-dimensional array, which shows, what the children of the
     			specified node are. So, in the first level, the index is the name of a chapter, and the
     			value is an array of subchapters that are identified by:
     			 - Name
     			 - Order
     
     			In the first stage, we simply load the list of TXT files from the directory. We sort them in
     			order to provide the standard alphanumerical sorting. The structure mentioned above is constructed
     			in the stage 2. We iterate through the filelist and explode each item with a dot. By cutting down the
     			last path element, we are able to specify the parent of the chapter. Now we do two things:
     			 - We create an empty list for the currently processed chapter.
     			 - We add the chapter to its parent children list.
     
     			The stage 3 applies the sorting hints from sort_hints.txt file. We load the file and use basically the
     			same algorithm, as in stage 2, to process its content. So, now we have two lists:
     			 - The first one, sorted alphanumerically
     			 - The second one, that uses the sorting hints.
     
     			In the stage 4, we simply connect them, by scanning the first list. We check, whether it figures in the
     			second one (that means we have to use hints instead of standard sorting). If yes, we copy the order. Once
     			it is completed, we run PHP sort again to apply the order physically.
     
     			Stage 5 creates some meta data for each page, as well as resolves the navigation issue.
     
     			*/
     // The tree structure is always built upon the base language directory content.
     $items = $this->fs->listDirectory('input/' . $this->baseLanguage . '/', true, true);
     // Stage 1
     // See, what are the documentation pages, and what - other files.
     $doc = array();
     foreach ($items as $item) {
         if (($s = strpos($item, '.txt')) !== false) {
             if ($s == strlen($item) - 4) {
                 $doc[] = substr($item, 0, $s);
             }
         } else {
             $this->media[] = $item;
         }
     }
     sort($doc);
     // Stage 2
     // Build the standard connections
     $list = array();
     foreach ($doc as &$item) {
         $extract = explode('.', $item);
         array_pop($extract);
         $parentId = implode('.', $extract);
         if (!isset($list[$parentId])) {
             if ($parentId != '') {
                 echo 'fool';
                 throw new Exception('The parent of "' . $item . '" does not exist.');
             }
             $list[$parentId] = array(0 => array('id' => $item, 'order' => 0));
         } else {
             $list[$parentId][] = array('id' => $item, 'order' => sizeof($list[$parentId]));
         }
         if (!isset($list[$item])) {
             $list[$item] = array();
         }
     }
     try {
         // Stage 3
         // If the hints are not defined, the exception will be thrown and
         // the stages 3 and 4 won't be executed.
         $this->sortHint = $this->fs->readAsArray('sort_hints.txt');
         $sortDuplicates = array_duplicates($this->sortHint);
         if (count($sortDuplicates) > 0) {
             foreach ($sortDuplicates as $duplicate) {
                 $this->prog->console->stdout->writeln('Duplicates of page "' . $duplicate . '" in sort hints.');
             }
             $this->sortHint = array_values(array_unique($this->sortHint));
         }
         $hintedList = array();
         foreach ($this->sortHint as &$item) {
             $extract = explode('.', $item);
             array_pop($extract);
             $parentId = implode('.', $extract);
             $exists = false;
             foreach ($list[$parentId] as &$subitem) {
                 if ($subitem['id'] == $item) {
                     $exists = true;
                     break;
                 }
             }
             if (!$exists) {
                 $this->prog->console->stdout->writeln('Sort hint for "' . $item . '" does not have existing page.');
                 unset($item);
                 continue;
             }
             if (!isset($hintedList[$parentId])) {
                 $hintedList[$parentId] = array($item => array('id' => $item, 'order' => 0));
             } else {
                 $hintedList[$parentId][$item] = array('id' => $item, 'order' => sizeof($hintedList[$parentId]));
             }
         }
         // Stage 4
         foreach ($list as $id => &$item) {
             if (isset($hintedList[$id])) {
                 foreach ($item as &$val) {
                     if (isset($hintedList[$id][$val['id']])) {
                         $val['order'] = $hintedList[$id][$val['id']]['order'];
                     } elseif (strlen($id) == 0) {
                         throw new Exception('Not all base chapters are defined in the sorting hint list. Missing: "' . $val['id'] . '". I don\'t know, what to do.');
                     } else {
                         throw new Exception('Not all children of "' . $id . '" are defined in the sorting hint list. Missing: "' . $val['id'] . '". I don\'t know, what to do.');
                     }
                 }
                 usort($item, array($this, 'orderSort'));
             }
         }
     } catch (SystemException $e) {
         // Nothing to worry, if the file is not accessible. At least the data won't be sorted.
         // TODO: However, if the debug is active, there must be some kind of message.
     }
     /*
      * Part 2 - create the meta-data for each page. (stage 5)
      */
     $this->pages = array();
     $parser = tfParsers::get();
     foreach ($list as $id => &$sublist) {
         foreach ($sublist as $subId => &$item) {
             // Try to load the content: first check the current language
             // if does not exist, load the base language file.
             $metaData = array();
             try {
                 /* If you remove the temporary variable below, you will be killed.
                  * Read the links below and think:
                  *  - http://bugs.php.net/bug.php?id=48408
                  *  - http://bugs.php.net/bug.php?id=48409
                  */
                 $tempVariable = $this->fs->get('input/' . $this->language . '/' . $item['id'] . '.txt');
                 $metaData = $parser->tfdoc($tempVariable);
             } catch (SystemException $e) {
                 $tempVariable = $this->fs->get('input/' . $this->baseLanguage . '/' . $item['id'] . '.txt');
                 $metaData = $parser->tfdoc($tempVariable);
             }
             // Create the additional meta.
             $metaData['Id'] = $item['id'];
             $metaData['Number'] = $item['order'] + 1;
             // Create the navigation according to the chapter layout
             $metaData['_Parent'] = $id;
             $metaData['_Previous'] = null;
             $metaData['_Next'] = null;
             if (isset($sublist[$subId - 1])) {
                 $metaData['_Previous'] = $sublist[$subId - 1]['Id'];
             }
             if (isset($sublist[$subId + 1])) {
                 $metaData['_Next'] = $sublist[$subId + 1]['id'];
             }
             if ($this->config['navigation'] == 'book') {
                 // Create a flat navigation, where "Next" can point to the first child, if accessible
                 $metaData['_XNext'] = $metaData['_Next'];
                 if (isset($this->pages[$metaData['Id']]['_Next'])) {
                     $metaData['_Next'] = $this->pages[$metaData['Id']]['_Next'];
                 }
                 if (!is_null($metaData['_Previous'])) {
                     $xid = $metaData['_Previous'];
                     while (($size = sizeof($list[$xid])) > 0) {
                         $xid = $list[$xid][$size - 1]['id'];
                     }
                     $metaData['_Previous'] = $xid;
                 } elseif (is_null($metaData['_Previous']) && $id != '') {
                     $metaData['_Previous'] = $id;
                 }
                 if (!is_null($metaData['_Previous'])) {
                     $this->pages[$metaData['_Previous']]['_Next'] = $metaData['Id'];
                 }
             }
             $item = $metaData;
             $this->pages[$item['Id']] =& $item;
         }
     }
     // Additional stage that adds the numbers
     $queue = new SplQueue();
     foreach ($list[''] as &$item) {
         $queue->enqueue($item['Id']);
     }
     // Add the numbering.
     $appendixEnum = 'A';
     while ($queue->count() > 0) {
         $id = $queue->dequeue();
         if (isset($this->pages[$id]['Tags']['Appendix']) && $this->pages[$id]['Tags']['Appendix']) {
             $this->pages[$id]['FullNumber'] = $appendixEnum++;
         } else {
             if ($this->pages[$id]['_Parent'] == '') {
                 $this->pages[$id]['FullNumber'] = $this->pages[$id]['Number'];
             } else {
                 $this->pages[$id]['FullNumber'] = $this->pages[$this->pages[$id]['_Parent']]['FullNumber'] . '.' . $this->pages[$id]['Number'];
             }
         }
         foreach ($list[$id] as &$item) {
             $queue->enqueue($item['Id']);
         }
     }
     $this->tree = $list;
 }
Example #2
0
         }
         $field =& $details['fields'][$curr_field['Field']]['db'];
         $props = CMbFieldSpec::parseDBSpec($curr_field['Type']);
         $field['type'] = $props['type'];
         $field['params'] = $props['params'];
         $field['unsigned'] = $props['unsigned'];
         $field['zerofill'] = $props['zerofill'];
         $field['null'] = $curr_field['Null'] != 'NO';
         $field['default'] = $curr_field['Default'];
         $field['index'] = null;
         $field['extra'] = $curr_field['Extra'];
     }
     // Extraction des Index
     $sql = "SHOW INDEX FROM `{$object->_spec->table}`";
     $list_indexes = $ds->loadList($sql);
     $duplicates = array_duplicates($list_indexes, 'Column_name');
     $details['duplicates'] = $duplicates;
     foreach ($list_indexes as $curr_index) {
         $details['fields'][$curr_index['Column_name']]['db']['index'] = $curr_index['Key_name'];
         if ($curr_index['Key_name'] == 'PRIMARY') {
             $details['db_key'] = $curr_index['Column_name'];
             if ($object->_spec->incremented) {
                 $details['fields'][$curr_index['Column_name']]['object']['db_spec']['extra'] = 'auto_increment';
             }
         }
     }
 } else {
     $details['no_table'] = true;
     $details['duplicates'] = array();
 }
 $details['suggestion'] = null;