Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
hipo_job_tool_search_replace.inc
1 <?php
17 require_once SQ_SYSTEM_ROOT.'/core/hipo/hipo_job.inc';
18 
32 {
33 
34 
40  function HIPO_Job_Tool_Search_Replace($code_name='')
41  {
42  $this->_hipo_vars['job_dir'] = SQ_PACKAGES_PATH.'/packages/search/tools/tool_search_replace';
43  $GLOBALS['SQ_SYSTEM']->lm->includeAssetStrings('tool_search_replace');
44  $this->HIPO_Job($code_name);
45 
46  }//end constructor
47 
48 
55  function getCodeName()
56  {
57  return parent::getCodeName().'-'.md5(implode('-',array_keys($this->_running_vars['search_data'])));
58 
59  }//end getCodeName()
60 
61 
68  function getHipoName()
69  {
70  return translate('sch_hipo_name_global_sr');
71 
72  }//end getHipoName()
73 
74 
82  function getInitialStepData()
83  {
84  return Array(
85  Array(
86  'name' => translate('hipo_confirmation'),
87  'function_call' => Array(
88  'paint_function' => 'paintConfirmation',
89  'process_function' => 'processConfirmation',
90  ),
91  'running_mode' => 'web',
92  'skip_step' => FALSE,
93  'auto_step' => FALSE,
94  'allow_cancel' => TRUE,
95  'percent_done' => 0,
96  'complete' => FALSE,
97  'message' => '',
98  ),
99  Array(
100  'name' => translate('hipo_acquiring_locks'),
101  'hipo_job' => Array(
102  'init_details_function' => 'getLockAssetDetails',
103  ),
104  'running_mode' => 'server',
105  'auto_step' => TRUE,
106  'allow_cancel' => FALSE,
107  'percent_done' => 0,
108  'complete' => FALSE,
109  'message' => '',
110  ),
111  Array(
112  'name' => translate('sch_hipo_replacing_asset_attributes'),
113  'function_call' => Array(
114  'process_function' => 'processAttributes',
115  ),
116  'running_mode' => 'server',
117  'skip_step' => FALSE,
118  'auto_step' => TRUE,
119  'allow_cancel' => TRUE,
120  'percent_done' => 0,
121  'complete' => FALSE,
122  'message' => '',
123  ),
124  Array(
125  'name' => translate('sch_hipo_replacing_asset_contents'),
126  'function_call' => Array(
127  'process_function' => 'processContent',
128  ),
129  'running_mode' => 'server',
130  'skip_step' => FALSE,
131  'auto_step' => TRUE,
132  'allow_cancel' => TRUE,
133  'percent_done' => 0,
134  'complete' => FALSE,
135  'message' => '',
136  ),
137  Array(
138  'name' => translate('sch_hipo_replacing_asset_metadata'),
139  'function_call' => Array(
140  'process_function' => 'processMetadata',
141  ),
142  'running_mode' => 'server',
143  'skip_step' => FALSE,
144  'auto_step' => TRUE,
145  'allow_cancel' => TRUE,
146  'percent_done' => 0,
147  'complete' => FALSE,
148  'message' => '',
149  ),
150  Array(
151  'name' => translate('sch_hipo_replacing_schema_values'),
152  'function_call' => Array(
153  'process_function' => 'processSchemas',
154  ),
155  'running_mode' => 'server',
156  'skip_step' => FALSE,
157  'auto_step' => TRUE,
158  'allow_cancel' => TRUE,
159  'percent_done' => 0,
160  'complete' => FALSE,
161  'message' => '',
162  ),
163  Array(
164  'name' => translate('hipo_releasing_locks'),
165  'function_call' => Array(
166  'process_function' => 'releaseLocks',
167  ),
168  'running_mode' => 'server',
169  'auto_step' => TRUE,
170  'skip_step' => FALSE,
171  'allow_cancel' => FALSE,
172  'percent_done' => 0,
173  'complete' => FALSE,
174  'message' => '',
175  ),
176  Array(
177  'name' => translate('sch_hipo_regenerating_metadata'),
178  'hipo_job' => Array(
179  'init_details_function' => 'getRegenerateMetadataDetails',
180  ),
181  'running_mode' => 'server',
182  'auto_step' => TRUE,
183  'allow_cancel' => FALSE,
184  'percent_done' => 0,
185  'complete' => FALSE,
186  'message' => '',
187  ),
188  Array(
189  'name' => translate('sch_hipo_reindexing_assets'),
190  'hipo_job' => Array(
191  'init_details_function' => 'getReindexAssetDetails',
192  ),
193  'running_mode' => 'server',
194  'auto_step' => TRUE,
195  'allow_cancel' => FALSE,
196  'percent_done' => 0,
197  'complete' => FALSE,
198  'message' => '',
199  ),
200  );
201 
202  }//end getInitialStepData()
203 
204 
211  function prepare()
212  {
213  if (array_key_exists('contextid', $this->_running_vars) === FALSE) {
214  trigger_localised_error('SCH0031', E_USER_WARNING);
215  return FALSE;
216  }
217 
218  return parent::prepare();
219 
220  }//end prepare()
221 
222 
233  function getLockAssetDetails(&$job_type, &$running_vars, &$options)
234  {
235  $job_type = 'hipo_job_acquire_locks';
236 
237  $options['auto_complete'] = TRUE;
238 
239  $running_vars = Array(
240  'assetids' => array_keys($this->_running_vars['search_data']),
241  'lock_type' => Array('all'),
242  'forceably_acquire' => FALSE,
243  'dependants_only' => TRUE,
244  );
245 
246  }//end getLockAssetDetails()
247 
248 
259  function getRegenerateMetadataDetails(&$job_type, &$running_vars, &$options)
260  {
261  $job_type = 'hipo_job_regenerate_metadata';
262 
263  $options['auto_complete'] = TRUE;
264 
265  $running_vars = Array(
266  'schemaids' => $this->_running_vars['schemaids'],
267  'contextids' => Array($this->_running_vars['contextid']),
268  );
269 
270  }//end getRegenerateMetadataDetails()
271 
272 
284  function getReindexAssetDetails(&$job_type, &$running_vars, &$options, &$hipo_vars)
285  {
286  $job_type = 'hipo_job_reindex';
287 
288  $options['auto_complete'] = TRUE;
289 
290  $running_vars = Array(
291  'root_assetid' => array_keys($this->_running_vars['search_data']),
292  'contextid' => $this->_running_vars['contextid'],
293  'root_only' => TRUE,
294  );
295 
296  $hipo_vars = Array(
297  'job_dir' => SQ_PACKAGES_PATH.'/search/hipo_jobs',
298  );
299 
300  }//end getReindexAssetDetails()
301 
302 
312  function releaseLocks(&$step_data, $prefix)
313  {
314  if (!isset($this->_running_vars['re_lock_assets'])) {
315  $this->_running_vars['re_lock_assets'] = array_keys($this->_running_vars['search_data']);
316  }
317 
318  $assetid = array_shift($this->_running_vars['re_lock_assets']);
319  unset($this->_running_vars['re_lock_assets'][$assetid]);
320 
321  $children = $GLOBALS['SQ_SYSTEM']->am->getDependantChildren($assetid);
322 
323  foreach ($children as $dep_child_id => $dep_child_type_code) {
324  $GLOBALS['SQ_SYSTEM']->am->releaseLock($dep_child_id, 'all');
325  }
326 
327  $asset_info = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(Array($assetid));
328 
329  $step_data['message'] = translate('sch_tool_global_sr_releasing_locks', $asset_info[$assetid]['name']);
330 
331  $GLOBALS['SQ_SYSTEM']->am->releaseLock($assetid, 'all');
332 
333  $this->_running_vars['done_assetids'][] = $assetid;
334 
335  if (empty($this->_running_vars['re_lock_assets'])) {
336  unset($this->_running_vars['done_assetids']);
337  $step_data['percent_done'] = 100;
338  $step_data['complete'] = TRUE;
339  } else {
340  $step_data['percent_done'] = (count($this->_running_vars['done_assetids']) / count(array_keys($this->_running_vars['search_data']))) * 100;
341  $step_data['complete'] = FALSE;
342  }
343 
344  return TRUE;
345 
346  }//end releaseLocks()
347 
348 
355  function _getSearchCounts()
356  {
357  $search_count = Array();
358  $search_string = preg_replace('/([\.\\\!\+\*\?\[\]\^\$\(\)\=\!<>\|\:\/]+)/i', '\\\${1}', $this->_running_vars['search_string']);
359 
360  foreach ($this->_running_vars['search_data'] as $assetid => $contents) {
361  $search_count[$assetid] = 0;
362 
363  foreach (Array('attributes', 'contents', 'metadata', 'schema') as $type) {
364  if (isset($contents[$type])) {
365 
366  foreach ($contents[$type] as $index => $value) {
367 
368  if ($type == 'metadata' || $type == 'schema') {
369  $value = $value['value'];
370  }
371 
372  $matches = Array();
373  preg_match_all("/$search_string/i", $value, $matches);
374  $search_count[$assetid] += count($matches[0]);
375  $cvrd_sch_str = htmlentities($search_string);
376  if ($cvrd_sch_str != $search_string) {
377  $matches = Array();
378  preg_match_all('/'.$cvrd_sch_str.'/i', $value, $matches);
379  $search_count[$assetid] += count($matches[0]);
380  }
381  unset($matches);
382  }
383  }
384  }
385 
386  }
387  return $search_count;
388 
389  }//end _getSearchCounts()
390 
391 
403  function paintConfirmation(&$step_data, &$o, $prefix)
404  {
405  $GLOBALS['SQ_SYSTEM']->changeContext($this->_running_vars['contextid']);
406 
407  $search_count = $this->_getSearchCounts();
408  $this->_setupMatches();
409  $this->save();
410  $o->openSection(translate('sch_tool_global_sr_confirmation'));
411  $o->openField('', 'replace_selection');
412 
413  ?>
414  <script type="text/javascript" src="<?php echo sq_web_path('data'); ?>/asset_types/tool_search_replace/js/search_and_replace.js"></script>
415 
416  <style type="text/css">
417  @import url(<?php echo sq_web_path('data'); ?>/asset_types/tool_search_replace/css/search_and_replace.css);
418  table.expandable thead th {
419  background-image: url(<?php echo sq_web_path('lib'); ?>/web/images/icons/expand_arrow.gif);
420  }
421  table thead th.match-checkbox, table thead th.all-asset-checkbox {
422  background-image: none;
423  }
424  </style>
425  <p style="text-align: center">
426  <span class="link" id="select-deselect-link-top" onclick="setAllCheckboxes(this)"><?php echo translate('sch_tool_global_sr_select_all'); ?></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
427  <span class="link" id="expand-collapse-link-top" onclick="toggleAllTbodyDisplays(this)" ><?php echo translate('sch_tool_global_sr_expand_all'); ?></span>
428  </p>
429 
430  <div id="confirmations-container">
431  <?php
432 
433  $names = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(array_keys($this->_running_vars['search_data']), '', FALSE, 'name');
434  foreach ($this->_running_vars['search_data'] as $assetid => $value) {
435  ?>
436  <table class="sq-backend-table expandable" style="margin-bottom: 10px">
437  <thead>
438  <tr>
439  <th onclick="toggleTBodyDisplay(this)">
440  <?php echo get_asset_tag_line($assetid); ?>
441  - <?php echo translate('sch_tool_global_sr_file_match(es)', $search_count[$assetid]); ?>
442  </th>
443  <th class="all-asset-checkbox">
444  <?php check_box($prefix.'_asset_'.$assetid.'_all', 1, FALSE, 'toggleTBodyCheckboxes(this)'); ?>
445  </th>
446  </tr>
447  </thead>
448  <tbody style="display: none">
449  <tr>
450  <td colspan="2">
451  <?php
452  // ATTRIBUTES
453  if (!empty($value['attributes'])) {
454  $this->_printAttributeMatches($assetid, $prefix, $value['attributes']);
455  }
456 
457  // METADATA
458  if (!empty($value['metadata'])) {
459  $this->_printMetadataMatches($assetid, $prefix, $value['metadata']);
460  }
461 
462  // CONTENTS
463  if (isset($value['contents'])) {
464  $this->_printContentMatches($assetid, $prefix, $value['contents']);
465  }
466 
467  // SCHEMA
468  if (isset($value['schema'])) {
469  $this->_printSchemaMatches($assetid, $prefix, $value['schema']);
470  }
471  ?>
472  </td>
473  </tr>
474  </tbody>
475  </table>
476  <?php
477 
478  }//end foreach asset
479 
480  ?>
481  </div>
482  <p style="text-align: center">
483  <span class="link" id="select-deselect-link-bottom" onclick="setAllCheckboxes(this)"><?php echo translate('sch_tool_global_sr_select_all'); ?></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
484  <span class="link" id="expand-collapse-link-bottom" onclick="toggleAllTbodyDisplays(this)" ><?php echo translate('sch_tool_global_sr_expand_all'); ?></span>
485  </p>
486  <?php
487 
488  $o->addHiddenField('form_submitted', 1);
489  $o->closeField();
490  $o->closeSection();
491 
492  $GLOBALS['SQ_SYSTEM']->restoreContext();
493 
494  return TRUE;
495 
496  }//end paintConfirmation()
497 
498 
508  function processConfirmation(&$step_data, $prefix)
509  {
510  if (!isset($_REQUEST['form_submitted'])) {
511  // No submission yet, need to print form;
512  return TRUE;
513  }
514  // Form has been submitted, now we can process it
515  $this->_updateSearchData($prefix);
516  $this->save();
517  if (empty($this->_running_vars['search_data'])) {
518  $this->skipStep(1);
519  $this->skipStep(2);
520  $this->skipStep(3);
521  $this->skipStep(4);
522  $this->skipStep(5);
523  $this->skipStep(6);
524  $this->skipStep(7);
525  $this->skipStep(8);
526  } else {
527  $this->_running_vars['attribute_replacements_total'] = 0;
528  $this->_running_vars['content_replacements_total'] = 0;
529  $this->_running_vars['metadata_replacements_total'] = 0;
530  $this->_running_vars['schema_replacements_total'] = 0;
531 
532  foreach ($this->_running_vars['search_data'] as $assetid => $value) {
533  if (isset($value['attributes'])) {
534  $this->_running_vars['attribute_replacements'][$assetid] = $value['attributes'];
535  $this->_running_vars['attribute_replacements_total']++;
536  }
537  if (isset($value['contents'])) {
538  $this->_running_vars['content_replacements'][$assetid] = $value['contents'];
539  $this->_running_vars['content_replacements_total']++;
540  }
541  if (isset($value['metadata'])) {
542  $this->_running_vars['metadata_replacements'][$assetid] = $value['metadata'];
543  $this->_running_vars['metadata_replacements_total']++;
544  }
545  if (isset($value['schema'])) {
546  $this->_running_vars['schema_replacements'][$assetid] = $value['schema'];
547  $this->_running_vars['schema_replacements_total']++;
548  $this->_running_vars['schemaids'][] = $assetid;
549  }
550  }
551  if ($this->_running_vars['attribute_replacements_total'] == 0) {
552  $this->skipStep(2);
553  }
554  if ($this->_running_vars['content_replacements_total'] == 0) {
555  $this->skipStep(3);
556  }
557  if ($this->_running_vars['metadata_replacements_total'] == 0) {
558  $this->skipStep(4);
559  }
560  if ($this->_running_vars['schema_replacements_total'] == 0) {
561  $this->skipStep(5);
562  $this->skipStep(7);
563  }
564  }//end else
565 
566  $step_data['percent_done'] = 100;
567  $step_data['complete'] = TRUE;
568 
569  return TRUE;
570 
571  }//end processConfirmation()
572 
573 
584  function _printAttributeMatches($assetid, $prefix, &$attr_matches)
585  {
586  ?>
587  <table class="sq-backend-table expandable component" border="1">
588  <thead>
589  <tr>
590  <th colspan="2" onclick="toggleTBodyDisplay(this)">
591  <?php echo translate('asset_attributes'); ?>
592  </th>
593  <th style="text-align: right" class="match-checkbox">
594  <?php check_box($prefix.'_asset_'.$assetid.'_attr_all', 1, FALSE, 'toggleTBodyCheckboxes(this); updateParentCheckboxes(this);', 'class="component-checkbox"'); ?>
595  </th>
596 
597  </tr>
598  </thead>
599  <tbody style="display: none">
600  <tr>
601  <th style="width: 30%"><?php echo translate('attribute_name'); ?></th>
602  <th><?php echo translate('match'); ?></th>
603  <th class="match-checkbox">&nbsp;</th>
604  </tr>
605  <?php
606  foreach ($attr_matches as $attr_name => $attr_details) {
607  foreach ($attr_details['matches'] as $offset) {
608  $html_id = $prefix.'_asset_'.$assetid.'_attr_'.$attr_name.'_'.$offset;
609  ?>
610  <tr>
611  <td><?php echo $attr_name; ?></th>
612  <td><label for="<?php echo $html_id; ?>"><?php $this->_printHighlightedMatch($this->_running_vars['search_string'], $attr_details['value'], $offset); ?></label></td>
613  <td class="match-checkbox"><?php check_box($html_id, 1, FALSE, 'updateParentCheckboxes(this)'); ?></td>
614  </tr>
615  <?php
616  }
617  }
618  ?>
619  </tbody>
620  </table>
621  <?php
622 
623  }//end _printAttributeMatches()
624 
625 
636  function _printMetadataMatches($assetid, $prefix, &$meta_matches)
637  {
638  ?>
639  <table class="sq-backend-table expandable component" border="1">
640  <thead>
641  <tr>
642  <th colspan="3" onclick="toggleTBodyDisplay(this)">
643  <?php echo translate('asset_metadata'); ?>
644  </th>
645  <th class="match-checkbox" style="text-align: right">
646  <?php check_box($prefix.'_asset_'.$assetid.'_attr_all', 1, FALSE, 'toggleTBodyCheckboxes(this); updateParentCheckboxes(this);', 'class="component-checkbox"'); ?>
647  </th>
648  </tr>
649  </thead>
650  <tbody style="display: none">
651  <tr>
652  <th><?php echo translate('field_id'); ?></th>
653  <th><?php echo translate('match'); ?></th>
654  <th>&nbsp;</th>
655  </tr>
656  <?php
657  foreach ($meta_matches as $field_id => $field_details) {
658  foreach ($field_details['matches'] as $offset) {
659  $html_id = $prefix.'_asset_'.$assetid.'_metadata_'.$field_id.'_'.$offset;
660  ?>
661  <tr>
662  <td><?php echo get_asset_tag_line($field_id); ?></th>
663  <td><?php echo $field_details['name']; ?></td>
664  <td><label for="<?php echo $html_id; ?>"><?php $this->_printHighlightedMatch($this->_running_vars['search_string'], $field_details['value'], $offset); ?></label></td>
665  <td class="match-checkbox"><?php check_box($html_id, 1, FALSE, 'updateParentCheckboxes(this)'); ?></td>
666  </tr>
667  <?php
668  }
669  }
670  ?>
671  </tbody>
672  </table>
673  <?php
674 
675  }//end _printMetadataMatches()
676 
677 
688  function _printSchemaMatches($assetid, $prefix, &$schema_matches)
689  {
690  ?>
691  <table class="sq-backend-table expandable component" border="1">
692  <thead>
693  <tr>
694  <th colspan="2" onclick="toggleTBodyDisplay(this)">
695  <?php echo translate('metadata_schema'); ?>
696  </th>
697  <th class="match-checkbox" style="text-align: right">
698  <?php check_box($prefix.'_asset_'.$assetid.'_attr_all', 1, FALSE, 'toggleTBodyCheckboxes(this); updateParentCheckboxes(this);', 'class="component-checkbox"'); ?>
699  </th>
700  </tr>
701  </thead>
702  <tbody style="display: none">
703  <tr>
704  <th><?php echo translate('field_id'); ?></th>
705  <th><?php echo translate('match'); ?></th>
706  <th>&nbsp</th>
707  </tr>
708  <?php
709  foreach ($schema_matches as $field_id => $schema_details) {
710  foreach ($schema_details['matches'] as $offset) {
711  $html_id = $prefix.'_asset_'.$assetid.'_schemafield_'.$field_id.'_'.$offset;
712  ?>
713  <tr>
714  <td><?php echo get_asset_tag_line($field_id); ?></th>
715  <td><label for="<?php echo $html_id; ?>"><?php $this->_printHighlightedMatch($this->_running_vars['search_string'], $schema_details['value'], $offset); ?></label></td>
716  <td class="match-checkbox"><?php check_box($html_id, 1, FALSE, 'updateParentCheckboxes(this)'); ?></td>
717  </tr>
718  <?php
719  }
720  }
721  ?>
722  </tbody>
723  </table>
724  <?php
725 
726  }//end _printSchemaMatches()
727 
728 
739  function _printContentMatches($assetid, $prefix, &$div_matches)
740  {
741  ?>
742  <table class="sq-backend-table expandable component" border="1">
743  <thead>
744  <tr>
745  <th colspan="2" onclick="toggleTBodyDisplay(this)">
746  <?php echo translate('asset_contents'); ?>
747  </th>
748  <th class="match-checkbox" style="text-align: right">
749  <?php check_box($prefix.'_asset_'.$assetid.'_content_all', 1, FALSE, 'toggleTBodyCheckboxes(this); updateParentCheckboxes(this);', 'class="component-checkbox"'); ?>
750  </th>
751  </tr>
752  </thead>
753  <tbody style="display: none">
754  <tr>
755  <th><?php echo translate('div_id'); ?></th>
756  <th><?php echo translate('match'); ?></th>
757  <th>&nbsp;</th>
758  </tr>
759  <?php
760  foreach ($div_matches as $div_id => $div_details) {
761  foreach ($div_details['matches'] as $offset) {
762  $html_id = $prefix.'_asset_'.$assetid.'_content_'.$div_id.'_'.$offset;
763  ?>
764  <tr>
765  <td><?php echo $div_id; ?></th>
766  <td><label for="<?php echo $html_id; ?>"><?php $this->_printHighlightedMatch($this->_running_vars['search_string'], $div_details['value'], $offset); ?></label></td>
767  <td class="match-checkbox"><?php check_box($html_id, 1, FALSE, 'updateParentCheckboxes(this)'); ?></td>
768  </tr>
769  <?php
770  }
771  }
772  ?>
773  </tbody>
774  </table>
775  <?php
776 
777  }//end _printContentMatches()
778 
779 
789  function processContent(&$step_data, $prefix)
790  {
791  $GLOBALS['SQ_SYSTEM']->changeContext($this->_running_vars['contextid']);
792 
793  $am =& $GLOBALS['SQ_SYSTEM']->am;
794  $search_string = $this->_running_vars['search_string'];
795  $replace_string = $this->_running_vars['replace_string'];
796  $assetid = key($this->_running_vars['content_replacements']);
797  $match_case = $this->_running_vars['match_case'];
798  $asset = $am->getAssetInfo(Array($assetid));
799 
800  $step_data['message'] = translate('sch_tool_global_sr_replacing_with_in', $search_string, $replace_string, $asset[$assetid]['name']);
801 
802  $asset_contents = $this->_running_vars['search_data'][$assetid]['contents'];
803  foreach ($asset_contents as $contents_id => $contents_value) {
804  $new_data = $this->_replaceOccurrences($search_string, $replace_string, $contents_value['value'], $contents_value['matches'], $match_case);
805  $am->setEditableContents($contents_id, $new_data);
806  }
807 
808  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($asset_contents);
809 
810  unset($this->_running_vars['content_replacements'][$assetid]);
811 
812  $this->_running_vars['done_assetids'][] = $assetid;
813 
814  if (empty($this->_running_vars['content_replacements'])) {
815  unset($this->_running_vars['done_assetids']);
816  $step_data['percent_done'] = 100;
817  $step_data['complete'] = TRUE;
818  } else {
819  $step_data['percent_done'] = (count($this->_running_vars['done_assetids']) / $this->_running_vars['content_replacements_total']) * 100;
820  $step_data['complete'] = FALSE;
821  }
822 
823  $GLOBALS['SQ_SYSTEM']->restoreContext();
824 
825  return TRUE;
826 
827  }//end processContent()
828 
829 
839  function processSchemas(&$step_data, $prefix)
840  {
841  $GLOBALS['SQ_SYSTEM']->changeContext($this->_running_vars['contextid']);
842 
843  $am =& $GLOBALS['SQ_SYSTEM']->am;
844 
845  $search_string = $this->_running_vars['search_string'];
846  $replace_string = $this->_running_vars['replace_string'];
847  $assetid = key($this->_running_vars['schema_replacements']);
848  $match_case = $this->_running_vars['match_case'];
849  $asset = $am->getAssetInfo(Array($assetid));
850 
851  $step_data['message'] = translate('sch_tool_global_sr_replacing_with_in', $search_string, $replace_string, $asset[$assetid]['name']);
852 
853  foreach ($this->_running_vars['schema_replacements'][$assetid] as $fieldid => $data) {
854  $new_data = $this->_replaceOccurrences($search_string, $replace_string, $data['value'], $data['matches'], $match_case);
855  $field = $am->getAsset($fieldid);
856  $value_component = Array();
857  $field->decodeValueString($new_data, $default_data, $value_component);
858  $field->setAttrValue('default', $default_data);
859  $field->saveAttributes();
860  $am->forgetAsset($field);
861  }
862 
863  unset($this->_running_vars['schema_replacements'][$assetid]);
864 
865  $this->_running_vars['done_assetids'][] = $assetid;
866 
867  if (empty($this->_running_vars['schema_replacements'])) {
868  unset($this->_running_vars['done_assetids']);
869  $step_data['percent_done'] = 100;
870  $step_data['complete'] = TRUE;
871  } else {
872  $step_data['percent_done'] = (count($this->_running_vars['done_assetids']) / $this->_running_vars['schema_replacements_total']) * 100;
873  $step_data['complete'] = FALSE;
874  }
875 
876  $GLOBALS['SQ_SYSTEM']->restoreContext();
877 
878  return TRUE;
879 
880  }//end processSchemas()
881 
882 
892  function processAttributes(&$step_data, $prefix)
893  {
894  $GLOBALS['SQ_SYSTEM']->changeContext($this->_running_vars['contextid']);
895 
896  $am =& $GLOBALS['SQ_SYSTEM']->am;
897 
898  $search_string = $this->_running_vars['search_string'];
899  $replace_string = $this->_running_vars['replace_string'];
900  $match_case = $this->_running_vars['match_case'];
901  $assetid = key($this->_running_vars['attribute_replacements']);
902 
903  $asset = $am->getAsset($assetid);
904 
905  $step_data['message'] = translate('sch_tool_global_sr_replacing_with_in', $search_string, $replace_string, $asset->name);
906 
907  foreach ($this->_running_vars['attribute_replacements'][$assetid] as $attrid => $data) {
908  $new_data = $this->_replaceOccurrences($search_string, $replace_string, $data['value'], $data['matches'], $match_case);
909  $asset->setAttrValue($attrid, $new_data);
910  }
911  $asset->saveAttributes();
912 
913  $am->forgetAsset($asset);
914  unset($this->_running_vars['attribute_replacements'][$assetid]);
915 
916  $this->_running_vars['done_assetids'][] = $assetid;
917 
918  if (empty($this->_running_vars['attribute_replacements'])) {
919  unset($this->_running_vars['done_assetids']);
920  $step_data['percent_done'] = 100;
921  $step_data['complete'] = TRUE;
922  } else {
923  $step_data['percent_done'] = (count($this->_running_vars['done_assetids']) / $this->_running_vars['attribute_replacements_total']) * 100;
924  $step_data['complete'] = FALSE;
925  }
926 
927  $GLOBALS['SQ_SYSTEM']->restoreContext();
928 
929  return TRUE;
930 
931  }//end processAttributes()
932 
933 
943  function processMetadata(&$step_data, $prefix)
944  {
945  $GLOBALS['SQ_SYSTEM']->changeContext($this->_running_vars['contextid']);
946 
947  $am =& $GLOBALS['SQ_SYSTEM']->am;
948  $mm = $GLOBALS['SQ_SYSTEM']->getMetadataManager();
949 
950  $search_string = $this->_running_vars['search_string'];
951  $replace_string = $this->_running_vars['replace_string'];
952  $match_case = $this->_running_vars['match_case'];
953  $assetid = key($this->_running_vars['metadata_replacements']);
954 
955  $asset = $am->getAssetInfo(Array($assetid));
956 
957  $step_data['message'] = translate('sch_tool_global_sr_replacing_with_in', $search_string, $replace_string, $asset[$assetid]['name']);
958 
959  $metadata = $mm->getMetadata($assetid);
960  // All context metadata files need to be regenerated if there is a non-contextable field changed
961  $regen_all_contexts = FALSE;
962  foreach ($this->_running_vars['metadata_replacements'][$assetid] as $fieldid => $data) {
963  $new_data = $this->_replaceOccurrences($search_string, $replace_string, $data['value'], $data['matches'], $match_case);
964  $metadata[$fieldid][0]['value'] = $new_data;
965  $field = $GLOBALS['SQ_SYSTEM']->am->getAsset($fieldid);
966  if (!$regen_all_contexts && (!$field->attr('is_contextable') || $field instanceof Metadata_Field_Select)) {
967  $regen_all_contexts = TRUE;
968  }
969  }
970 
971  $mm->setMetadata($assetid, $metadata);
972  if ($regen_all_contexts) {
973  $all_contexts = $GLOBALS['SQ_SYSTEM']->getAllContexts();
974  foreach ($all_contexts as $contextid => $context_data) {
975  $mm->generateContentFile($assetid, FALSE, $contextid);
976  }
977  } else {
978  $mm->generateContentFile($assetid);
979  }
980 
981  unset($this->_running_vars['metadata_replacements'][$assetid]);
982 
983  $this->_running_vars['done_assetids'][] = $assetid;
984 
985  if (empty($this->_running_vars['metadata_replacements'])) {
986  unset($this->_running_vars['done_assetids']);
987  $step_data['percent_done'] = 100;
988  $step_data['complete'] = TRUE;
989  } else {
990  $step_data['percent_done'] = (count($this->_running_vars['done_assetids']) / $this->_running_vars['metadata_replacements_total']) * 100;
991  $step_data['complete'] = FALSE;
992  }
993 
994  $GLOBALS['SQ_SYSTEM']->restoreContext();
995 
996  return TRUE;
997 
998  }//end processMetadata()
999 
1000 
1010  function _getOccurrences($needle, $haystack)
1011  {
1012  $occurrences = Array();
1013  $offset = 0;
1014  $needle = strtolower($needle);
1015  $haystack = strtolower($haystack);
1016  $result = strpos($haystack, $needle);
1017  while (FALSE !== $result) {
1018  $occurrences[] = $result;
1019  $offset = $result + strlen($needle);
1020  $result = strpos($haystack, $needle, $offset);
1021  }
1022 
1023  // Bug Fix 2076 and additional fix for Bug Fix 1575
1024  // Only perform the following block if html encoded needle is not the same as
1025  // the original needle. Or not we have the duplicated entries in the result array
1026  $html_encoded_needle = htmlentities($needle);
1027  if ($needle != $html_encoded_needle) {
1028  $offset = 0;
1029  $result = strpos($haystack, $html_encoded_needle);
1030  while (FALSE !== $result) {
1031  $occurrences[] = $result;
1032  $offset = $result + strlen($needle);
1033  $result = strpos($haystack, $html_encoded_needle, $offset);
1034  }
1035  }
1036  return $occurrences;
1037 
1038  }//end _getOccurrences()
1039 
1040 
1053  function _replaceOccurrences($needle, $new_needle, $haystack, $offsets, $case_match=FALSE)
1054  {
1055  if (empty($offsets)) return $haystack;
1056  $search_len = strlen($needle);
1057  $encoded_search_len = strlen(htmlentities($needle));
1058  $result_str = '';
1059  $last_offset = 0;
1060  foreach ($offsets as $id => $offset) {
1061  $encoded = (strtolower(substr($haystack, $offset, $search_len)) != strtolower($needle));
1062  $this_search_len = $encoded ? $encoded_search_len : $search_len;
1063  $rep_str = $new_needle;
1064  if ($case_match) {
1065  $rep_str = $this->_matchCapitals(substr($haystack, $offset, $this_search_len), $new_needle);
1066  }
1067  $result_str .= substr($haystack, $last_offset, $offset - $last_offset).$rep_str;
1068  $last_offset = $offset + $this_search_len;
1069  }
1070  $result_str .= substr($haystack, $last_offset);
1071  return $result_str;
1072 
1073  }//end _replaceOccurrences()
1074 
1075 
1085  function _matchCapitals($teacher, $student)
1086  {
1087  $ret_str = $student;
1088  if (strtoupper($teacher) == $teacher) {
1089  $ret_str = strtoupper($student);
1090  } else if (strtoupper($teacher[0]) == $teacher[0]) {
1091  $ret_str[0] = strtoupper($ret_str[0]);
1092  } else if (strtolower($teacher[0]) == $teacher[0]) {
1093  $ret_str[0] = strtolower($ret_str[0]);
1094  }
1095  return $ret_str;
1096 
1097  }//end _matchCapitals()
1098 
1099 
1109  function _printRows($needle, $haystack)
1110  {
1111  $occ = $this->_getOccurrences($needle, $haystack);
1112  foreach ($occ as $id => $offset) {
1113  echo '<tr><td><input type="checkbox" /></td><td>';
1114  $this->_printHighlightedMatch($needle, $haystack, $offset);
1115  echo '</td></tr>';
1116  }
1117 
1118  }//end _printRows()
1119 
1120 
1131  function _printHighlightedMatch($needle, $haystack, $offset)
1132  {
1133  if (substr($haystack, $offset, strlen($needle)) != $needle) {
1134  $needle = htmlentities($needle);
1135  }
1136  $back_limit = $this->_findBackBreak($haystack, $offset);
1137  $forward_limit = $this->_findForwardbreak($haystack, $offset + strlen($needle));
1138  echo htmlentities(ltrim(substr($haystack, $back_limit, $offset - $back_limit), '\n\r'));
1139  echo '<span style="background:yellow">'.$needle.'</span>';
1140  echo htmlentities(rtrim(substr($haystack, $offset + strlen($needle), $forward_limit - ($offset + strlen($needle)))));
1141 
1142  }//end _printHighlightedMatch()
1143 
1144 
1155  function _findBackBreak($haystack, $offset, $limit=20)
1156  {
1157  $ret = $offset;
1158  while ($ret > $offset - 200 && $ret > 0) {
1159  if ($haystack[$ret] == '>') {
1160  break;
1161  } else if ($haystack[$ret] == '<') {
1162  return $ret;
1163  }
1164  $ret--;
1165  }
1166  if ($ret == 0) return $ret;
1167  $ret = $offset;
1168  $oldspace = $ret - $limit;
1169  while ($ret > $offset - $limit && $ret > 0) {
1170  switch ($haystack[$ret]) {
1171  case '\n':
1172  case '<':
1173  return $ret ;
1174  case ' ':
1175  case '.':
1176  case ';':
1177  case ')':
1178  $oldspace = $ret;
1179  break;
1180 
1181  }
1182  $ret--;
1183  }
1184  return $oldspace;
1185 
1186  }//end _findBackBreak()
1187 
1188 
1199  function _findForwardBreak($haystack, $offset, $limit=55)
1200  {
1201  $end_tag = $offset;
1202  while (($end_tag < $offset + 200) && ($end_tag < strlen($haystack))) {
1203  if ($haystack[$end_tag] == '<') {
1204  break;
1205  } else if ($haystack[$end_tag] == '>') {
1206  $end_tag++;
1207  break;
1208  }
1209  $end_tag++;
1210  }
1211  $ret = $offset;
1212  $oldspace = $offset + $limit;
1213  while (($ret < $offset + $limit) && ($ret < strlen($haystack))) {
1214  switch ($haystack[$ret]) {
1215  case '\n':
1216  case '<br>':
1217  return $ret + 1;
1218  break;
1219  case ' ':
1220  case '.':
1221  case ';':
1222  case ')':
1223  case '-':
1224  case ',':
1225  case '!':
1226  $oldspace = $ret + 1;
1227  break;
1228  }
1229  $ret++;
1230  }
1231  if ($end_tag > $oldspace) return $end_tag;
1232  return $oldspace;
1233 
1234  }//end _findForwardBreak()
1235 
1236 
1243  function _setupMatches()
1244  {
1245  foreach ($this->_running_vars['search_data'] as $assetid => $details) {
1246  if (isset($details['attributes'])) {
1247  foreach ($details['attributes'] as $attr_name => $attr_val) {
1248  $this->_running_vars['search_data'][$assetid]['attributes'][$attr_name] = Array('value' => $attr_val);
1249  $this->_running_vars['search_data'][$assetid]['attributes'][$attr_name]['matches'] = $this->_getOccurrences($this->_running_vars['search_string'], $attr_val);
1250  }
1251  }
1252  if (isset($details['contents'])) {
1253  foreach ($details['contents'] as $div_id => $div_cont) {
1254  $this->_running_vars['search_data'][$assetid]['contents'][$div_id] = Array('value' => $div_cont);
1255  $this->_running_vars['search_data'][$assetid]['contents'][$div_id]['matches'] = $this->_getOccurrences($this->_running_vars['search_string'], $div_cont);
1256  }
1257  }
1258  if (isset($details['metadata'])) {
1259  foreach ($details['metadata'] as $schema_id => $schema_details) {
1260  $this->_running_vars['search_data'][$assetid]['metadata'][$schema_id]['matches'] = $this->_getOccurrences($this->_running_vars['search_string'], $schema_details['value']);
1261  }
1262  }
1263  if (isset($details['schema'])) {
1264  foreach ($details['schema'] as $schema_id => $schema_details) {
1265  $this->_running_vars['search_data'][$assetid]['schema'][$schema_id]['matches'] = $this->_getOccurrences($this->_running_vars['search_string'], $schema_details['value']);
1266  }
1267  }
1268  }
1269 
1270  }//end _setupMatches()
1271 
1272 
1281  function _updateSearchData($prefix)
1282  {
1283  foreach ($this->_running_vars['search_data'] as $assetid => $values) {
1284  // attributes
1285  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_all'])) {
1286  if (isset($this->_running_vars['search_data'][$assetid]['attributes'])) {
1287  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_attr_all'])) {
1288  foreach ($this->_running_vars['search_data'][$assetid]['attributes'] as $attr_name => $attr_details) {
1289  foreach ($attr_details['matches'] as $m) {
1290  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_attr_'.$attr_name.'_'.$m])) {
1291  $i = array_search($m, $this->_running_vars['search_data'][$assetid]['attributes'][$attr_name]['matches']);
1292  unset($this->_running_vars['search_data'][$assetid]['attributes'][$attr_name]['matches'][$i]);
1293  }
1294  }
1295  if (empty($this->_running_vars['search_data'][$assetid]['attributes'][$attr_name]['matches'])) {
1296  unset($this->_running_vars['search_data'][$assetid]['attributes'][$attr_name]);
1297  }
1298  }
1299  if (empty($this->_running_vars['search_data'][$assetid]['attributes'])) {
1300  unset($this->_running_vars['search_data'][$assetid]['attributes']);
1301  }
1302  }
1303  }
1304  // contents
1305  if (isset($this->_running_vars['search_data'][$assetid]['contents'])) {
1306  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_content_all'])) {
1307  foreach ($this->_running_vars['search_data'][$assetid]['contents'] as $div_id => $div_details) {
1308  foreach ($div_details['matches'] as $m) {
1309  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_content_'.$div_id.'_'.$m])) {
1310  $i = array_search($m, $this->_running_vars['search_data'][$assetid]['contents'][$div_id]['matches']);
1311  unset($this->_running_vars['search_data'][$assetid]['contents'][$div_id]['matches'][$i]);
1312  }
1313  }
1314  if (empty($this->_running_vars['search_data'][$assetid]['contents'][$div_id]['matches'])) {
1315  unset($this->_running_vars['search_data'][$assetid]['contents'][$div_id]);
1316  }
1317  }
1318  if (empty($this->_running_vars['search_data'][$assetid]['contents'])) {
1319  unset($this->_running_vars['search_data'][$assetid]['contents']);
1320  }
1321  }
1322  }
1323  // metadata
1324  if (isset($this->_running_vars['search_data'][$assetid]['metadata'])) {
1325  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_metadata_all'])) {
1326  foreach ($this->_running_vars['search_data'][$assetid]['metadata'] as $field_id => $field_details) {
1327  foreach ($field_details['matches'] as $m) {
1328  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_metadata_'.$field_id.'_'.$m])) {
1329  $i = array_search($m, $this->_running_vars['search_data'][$assetid]['metadata'][$field_id]['matches']);
1330  unset($this->_running_vars['search_data'][$assetid]['metadata'][$field_id]['matches'][$i]);
1331  }
1332  }
1333  if (empty($this->_running_vars['search_data'][$assetid]['metadata'][$field_id]['matches'])) {
1334  unset($this->_running_vars['search_data'][$assetid]['metadata'][$field_id]);
1335  }
1336  }
1337  if (empty($this->_running_vars['search_data'][$assetid]['metadata'])) {
1338  unset($this->_running_vars['search_data'][$assetid]['metadata']);
1339  }
1340  }
1341  }
1342  // schema
1343  if (isset($this->_running_vars['search_data'][$assetid]['schema'])) {
1344  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_schema_all'])) {
1345  foreach ($this->_running_vars['search_data'][$assetid]['schema'] as $field_id => $field_details) {
1346  foreach ($field_details['matches'] as $m) {
1347  if (!isset($_REQUEST[$prefix.'_asset_'.$assetid.'_schemafield_'.$field_id.'_'.$m])) {
1348  $i = array_search($m, $this->_running_vars['search_data'][$assetid]['schema'][$field_id]['matches']);
1349  unset($this->_running_vars['search_data'][$assetid]['schema'][$field_id]['matches'][$i]);
1350  }
1351  }
1352  if (empty($this->_running_vars['search_data'][$assetid]['schema'][$field_id]['matches'])) {
1353  unset($this->_running_vars['search_data'][$assetid]['schema'][$field_id]);
1354  }
1355  }
1356  if (empty($this->_running_vars['search_data'][$assetid]['schema'])) {
1357  unset($this->_running_vars['search_data'][$assetid]['schema']);
1358  }
1359  }
1360  }
1361  }//end if
1362  if (empty($this->_running_vars['search_data'][$assetid])) {
1363  unset($this->_running_vars['search_data'][$assetid]);
1364  }
1365  }//end foreach
1366 
1367  }//end _updateSearchData()
1368 
1369 
1370 }//end class
1371 
1372 
1373 ?>