Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
reindexSearchIndex.php
1 <?php
27 error_reporting(E_ALL);
28 if (ini_get('memory_limit') != '-1') ini_set('memory_limit', '-1');
29 
30 if ((php_sapi_name() != 'cli')) {
31  trigger_error("You can only run this script from the command line\n", E_USER_ERROR);
32 }
33 
34 $SYSTEM_ROOT = (isset($_SERVER['argv'][1])) ? $_SERVER['argv'][1] : '';
35 
36 // Check for valid system root
37 $SYSTEM_ROOT = (isset($_SERVER['argv'][1])) ? $_SERVER['argv'][1] : '';
38 if (empty($SYSTEM_ROOT)) {
39  echo "ERROR: You need to supply the path to the System Root as the first argument\n";
40  printUsage();
41  exit(1);
42 }
43 
44 if (!is_dir($SYSTEM_ROOT) || !is_readable($SYSTEM_ROOT.'/core/include/init.inc')) {
45  echo "ERROR: Path provided doesn't point to a Matrix installation's System Root. Please provide correct path and try again.\n";
46  printUsage();
47  exit(1);
48 }
49 
50 // File to communicate between the child and parent process
51 define('SYNC_FILE', $SYSTEM_ROOT.'/data/temp/reindex_search.assetids');
52 
53 $ROOT_NODES = (isset($_SERVER['argv'][2])) ? $_SERVER['argv'][2] : 1;
54 $root_node_ids = array_unique(explode(',', trim($ROOT_NODES, ' ,')));
55 if (in_array(1, $root_node_ids)) {
56  echo "Do you want to reindex the whole system (yes/no) ";
57  $process = trim(fgets(STDIN, 4094));
58  if (trim(strtolower($process)) != 'yes') {
59  echo "Aborting script.\n";
60  exit();
61  }
62 
63  // Since main root node is selected, we just need to reindex one root node
64  $root_node_ids = array(1);
65 }
66 
67 // Use the batch size of 100 assets by default
68 $BATCH_SIZE = (isset($_SERVER['argv'][3])) ? $_SERVER['argv'][3] : 100;
69 if ($BATCH_SIZE <= 0) {
70  $BATCH_SIZE = 100;
71 }
72 
73 $pid = fork();
74 if (!$pid) {
75 
76  // NOTE: This seemingly ridiculousness allows us to workaround Oracle, forking and CLOBs
77  // if a query is executed that returns more than 1 LOB before a fork occurs,
78  // the Oracle DB connection will be lost inside the fork.
79 
80  require_once $SYSTEM_ROOT.'/core/include/init.inc';
81 
82  $root_user = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('root_user');
83  $GLOBALS['SQ_SYSTEM']->setCurrentUser($root_user);
84 
85  // The index should be turned on in the system
86  $sm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('search_manager');
87  if (!$sm->attr('indexing')) {
88  echo "Search indexing is not turned on.\n\n";
89  file_put_contents(SYNC_FILE, serialize(Array('assetids' => Array(), 'contextids' => Array())));
90  exit();
91  }
92 
93  $all_assetids = Array();
94  foreach ($root_node_ids as $root_node_id) {
95 
96  // if the asset does not exist
97  if (!$GLOBALS['SQ_SYSTEM']->am->getAssetInfo($root_node_id)) {
98  echo "\nWARNING: The asset #".$root_node_id." is not valid assetid\n";
99  continue;
100  }
101  // Get the assets under the root node
102  $all_assetids = array_merge($all_assetids, array_keys($GLOBALS['SQ_SYSTEM']->am->getChildren($root_node_id)));
103  $all_assetids[] = $root_node_id;
104 
105  }//end foreach
106 
107  $all_assetids = array_unique($all_assetids);
108  $asset_count = count($all_assetids);
109 
110  // Chunk the assets into the given batch size
111  $start_index = 0;
112  $batched_assetids = Array();
113  while($start_index < $asset_count) {
114  $batched_assetids[] = array_slice($all_assetids, $start_index, $BATCH_SIZE);
115  $start_index += $BATCH_SIZE;
116  }//end while
117  $GLOBALS['SQ_SYSTEM']->restoreCurrentUser();
118 
119  // Also get the context ids
120  $contextids = array_keys($GLOBALS['SQ_SYSTEM']->getAllContexts());
121 
122  // Write the data to the sync file for the parent process to read from
123  file_put_contents(SYNC_FILE, serialize(Array('assetids' => $batched_assetids, 'contextids' => $contextids)));
124 
125  exit;
126 
127 }//end child process
128 
129 // Get the assetid data from the child process
130 $data = unserialize(file_get_contents(SYNC_FILE));
131 $batched_assetids = $data['assetids'];
132 $all_contextids = $data['contextids'];
133 
134 echo "Batch size: ".$BATCH_SIZE."\n";
135 echo "Total assets to reindex: ".(count($batched_assetids, COUNT_RECURSIVE) - count($batched_assetids))."\n\n";
136 
137 if (!empty($batched_assetids)) {
138  echo "Reindexing ...";
139  // Reindex each batch in the seperate process
140  foreach($batched_assetids as $assetids) {
141 
142  $pid = fork();
143  if (!$pid) {
144 
145  require_once $SYSTEM_ROOT.'/core/include/init.inc';
146 
147  $root_user = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('root_user');
148  $GLOBALS['SQ_SYSTEM']->setCurrentUser($root_user);
149 
150  $sm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('search_manager');
151 
152  // Child process
153  foreach($all_contextids as $contextid) {
154  $GLOBALS['SQ_SYSTEM']->changeContext($contextid);
155 
156  foreach($assetids as $assetid) {
157  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
158  if (is_null($asset)) {
159  continue;
160  }
161  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
162  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
163 
164  $sm->reindexAsset($asset, Array('all'));
165  $sm->reindexAttributes($asset, Array('all'), TRUE);
166  $sm->reindexContents($asset, Array('all'), TRUE);
167  $sm->reindexMetadata($asset->id, Array('all'));
168 
169  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
170  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
171 
172  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($asset);
173 
174  }//end foreach
175 
176  $GLOBALS['SQ_SYSTEM']->restoreContext();
177  }//end foreach
178 
179  $GLOBALS['SQ_SYSTEM']->restoreCurrentUser();
180 
181  exit;
182  }//end child process
183  echo ".";
184  }//end foreach
185  echo " Done.\n";
186 }//end if
187 
188 
189 if (file_exists(SYNC_FILE)) {
190  unlink(SYNC_FILE);
191 }
192 
193 exit();
194 
195 // END OF THE MAIN PROGRAM ////////////////////////////////////////////
196 
197 
198 /*
199 * Fork child process. The parent process will sleep until the child
200 * exits
201 *
202 * @return string
203 * @access public
204 */
205 function fork()
206 {
207  $child_pid = pcntl_fork();
208 
209  switch ($child_pid) {
210  case -1:
211  trigger_error("Forking failed!");
212  return null;
213  break;
214  case 0: // child process
215  return $child_pid;
216  break;
217  default : // parent process
218  $status = null;
219  pcntl_waitpid(-1, $status);
220  return $child_pid;
221  break;
222  }
223 }//end fork()
224 
225 
230 function printUsage()
231 {
232  echo "Usage: php ".basename(__FILE__)." <SYSTEM_ROOT> [ROOT_NODES] [BATCH_SIZE]\n\n";
233  echo "\t<SYSTEM_ROOT>:\t The root directory of the Matrix system.\n";
234  echo "\t[ROOT_NODES]:\t Comma seperated root node assetids to reindex. If ommited, whole system will be reindexed.\n";
235  echo "\t[BATCH_SIZE]:\t Number of assets to include in a batch. Default size is 100\n\n";
236 
237 }//end print_usage()
238 
239 ?>