Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
cron_job_future_lineage.inc
1 <?php
18 require_once SQ_CORE_PACKAGE_PATH.'/system/cron/cron_job/cron_job.inc';
19 
32 {
33 
34 
35 
36 
43  function __construct($assetid=0)
44  {
45  $this->_ser_attrs = TRUE;
46  parent::__construct($assetid);
47 
48  }//end constructor
49 
50 
59  protected function _createAdditional(Array &$link)
60  {
61  if (!parent::_createAdditional($link)) return FALSE;
62 
63  if (!empty($this->_tmp['asset_in_link'])) {
64  if (!$GLOBALS['SQ_SYSTEM']->am->acquireLock($this->id, 'links')) {
65  trigger_localised_error('CRON0018', E_USER_WARNING);
66  return FALSE;
67  }
68 
69  foreach ($this->_tmp['asset_in_link'] as $side_of_link => $link) {
70  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
71  if (is_null($asset) || !$this->setAssetInLink($asset, $side_of_link)) {
72  trigger_localised_error('CRON0017', E_USER_WARNING);
73  return FALSE;
74  }
75  }
76  unset($this->_tmp['asset_in_link']);
77  $GLOBALS['SQ_SYSTEM']->am->releaseLock($this->id, 'links');
78  }
79  return TRUE;
80 
81  }//end _createAdditional()
82 
83 
93  protected function _getName($short_name=FALSE)
94  {
95  $asset = $this->attr('reverse_mode') ? $this->getAssetInLink('major') : $this->getAssetInLink('minor');
96  if (is_null($asset)) {
97  return translate('cron_job_asset-less_future_linking');
98  } else if ($short_name) {
99  return translate('cron_fl_for', translate('asset_format', $asset->short_name, $asset->id));
100  } else {
101  return translate('cron_future_linking_for', translate('asset_format', $asset->name, $asset->id));
102  }//end if
103 
104  }//end _getName()
105 
106 
114  public function _getAllowedLinks()
115  {
116  $links = parent::_getAllowedLinks();
117 
118  // make sure that we can link to every asset
119  if (empty($links[SQ_LINK_NOTICE]['asset'])) {
120  $links[SQ_LINK_NOTICE]['asset'] = Array('card' => 2);
121  }
122 
123  return $links;
124 
125  }//end _getAllowedLinks()
126 
127 
136  public function canDelete()
137  {
138  if (parent::canDelete()) return TRUE;
139 
140  $asset = $this->attr('reverse_mode') ? $this->getAssetInLink('major') : $this->getAssetInLink('minor');
141  if (!is_null($asset)) return $asset->adminAccess('');
142  return FALSE;
143 
144  }//end canDelete()
145 
146 
156  public function setAttrValue($name, $value)
157  {
158  switch ($name) {
159  case 'type':
160  trigger_localised_error('CRON0039', E_USER_NOTICE);
161  return FALSE;
162  break;
163  case 'delete_linkid':
164  if ($value > 0) {
165  $this->setAttrValue('delete_link_all', FALSE);
166  }
167  break;
168  case 'delete_link_all':
169  if ($value == TRUE) {
170  $this->setAttrValue('delete_linkid', 0);
171  }
172  break;
173  }
174 
175  return parent::setAttrValue($name, $value);
176 
177  }//end setAttrValue()
178 
179 
189  public function setAssetInLink(Asset $asset, $side_of_link)
190  {
191  if ($side_of_link != 'major' && $side_of_link != 'minor') {
192  trigger_localised_error('CRON0033', E_USER_WARNING, $side_of_link);
193  return FALSE;
194  }
195 
196  if (!($asset instanceof Asset)) {
197  trigger_localised_error('CRON0030', E_USER_WARNING);
198  return FALSE;
199  }
200 
201  if ($this->id) {
202  return (bool) $this->createLink($asset, SQ_LINK_NOTICE, $side_of_link.'_asset');
203  } else {
204  if (!isset($this->_tmp['asset_in_link'])) {
205  $this->_tmp['asset_in_link'] = Array();
206  }
207  $this->_tmp['asset_in_link'][$side_of_link] = Array('minorid' => $asset->id, 'minor_type_code' => $asset->type());
208  return TRUE;
209  }
210 
211  }//end setAssetInLink()
212 
213 
222  public function getAssetInLink($side_of_link)
223  {
224  $null = NULL; // because we need to return by ref
225  if ($side_of_link != 'major' && $side_of_link != 'minor') {
226  trigger_localised_error('CRON0033', E_USER_WARNING, $side_of_link);
227  return $null;
228  }
229 
230  if ($this->id) {
231  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_NOTICE, 'asset', FALSE, $side_of_link.'_asset');
232  } else {
233  $link = (isset($this->_tmp['asset_in_link'][$side_of_link])) ? $this->_tmp['asset_in_link'][$side_of_link] : Array();
234  }
235 
236  if (empty($link)) return $null;
237  return $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
238 
239  }//end getAssetInLink()
240 
241 
248  public function readableDescription()
249  {
250  if($this->attr('reverse_mode')) return $this->_readableDescriptionReverse();
251 
252  $minor = $this->getAssetInLink('minor');
253 
254 
255  if (is_null($minor)) {
256  return translate('no_minor_asset_found');
257  }
258 
259 
260  $str = '';
261 
262  if ($this->attr('delete_linkid')) {
263  $str .= translate('deleting_link_id', $this->attr('delete_linkid'));
264  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkById($this->attr('delete_linkid'));
265 
266  if (!empty($link)) {
267  $old_major = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['majorid'], $link['major_type_code']);
268  if (!is_null($old_major)) {
269  $str = translate('delete_link_for', translate('asset_format', $minor->name, $minor->id), translate('asset_format', $old_major->name, $old_major->id));
270  }
271  }
272  }
273 
274  $new_major = $this->getAssetInLink('major');
275 
276  if ($this->attr('delete_linkid') && !is_null($new_major)) {
277  $str .= "\n";
278  }
279 
280  if (!is_null($new_major)) {
281  $str .= translate('create_new_link_for', translate('asset_format', $minor->name, $minor->id), translate('asset_format', $new_major->name, $new_major->id));
282  }
283 
284  return $str;
285 
286  }//end readableDescription()
287 
294  public function _readableDescriptionReverse()
295  {
296  $major = $this->getAssetInLink('major');
297  $new_minor = $this->getAssetInLink('minor');
298 
299  if(is_null($major)){
300  return translate('no_major_asset_found');
301  }
302 
303  $str = '';
304 
305  if ($this->attr('delete_linkid')) {
306  $str .= translate('deleting_link_id', $this->attr('delete_linkid'));
307  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkById($this->attr('delete_linkid'));
308 
309  if (!empty($link)) {
310  $old_minor = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
311  if (!is_null($old_minor)) {
312  $str = translate('delete_link_for', translate('asset_format', $old_minor->name, $old_minor->id), translate('asset_format', $major->name, $major->id));
313  }
314 
315  }
316  }
317 
318 
319  if ($this->attr('delete_linkid') && !is_null($new_minor)) {
320  $str .= "\n";
321  }
322 
323  if (!is_null($new_minor)) {
324  $str .= translate('create_new_link_for', translate('asset_format', $new_minor->name, $new_minor->id), translate('asset_format', $major->name, $major->id));
325  }
326 
327  return $str;
328 
329  }//end _readableDescriptionReverse()
330 
331 
343  protected function _exec(&$msg)
344  {
345  // we can be removed because the error is beyound our control
346  $failed_ret_val = SQ_CRON_JOB_ERROR | SQ_CRON_JOB_REMOVE;
347 
348  // need to get this here because we are could be deleting the link below
349 
350  $desc = $this->readableDescription();
351  $major = $this->getAssetInLink('major');
352  $minor = $this->getAssetInLink('minor');
353 
354  //in reverse mode, the current asset is major asset
355  $main_asset = $this->attr('reverse_mode') ? $major : $minor;
356  $target_asset = $this->attr('reverse_mode') ? $minor : $major;
357  $side_of_link = $this->attr('reverse_mode') ? 'major' : 'minor';
358 
359 
360  if (is_null($main_asset)) {
361  trigger_localised_error('CRON0019', E_USER_WARNING);
362  return $failed_ret_val;
363  }
364 
365 
366  // if we are moving to the trash folder, we need to check if the safe trash pref has been enabled
367 
368  $safe_trash = $GLOBALS['SQ_SYSTEM']->getUserPrefs('user', 'SQ_USER_SAFE_TYPE3_TRASH');
369  $can_safe_trash = TRUE;
370 
371  if ($safe_trash) {
372  $exclude_self = FALSE;
373  //if minor asset is empty, it must be deletion of children links
374  // so have to check the minor asset/assets
375  if(empty($minor)){
376  if ($this->attr('delete_link_all')){
377  $minor = $major;
378  $exclude_self = TRUE;
379  }
380  else if($this->attr('delete_linkid') > 0){
381  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkById($this->attr('delete_linkid'));
382  $minor = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
383  }
384 
385  }
386 
387  $can_safe_trash = $this->_canSafeTrash($minor, $exclude_self);
388  }
389 
390  $existing_links = Array();
391  if ($this->attr('delete_link_all') == TRUE && $can_safe_trash) {
392  $links = $GLOBALS['SQ_SYSTEM']->am->getLinks($main_asset->id, SQ_SC_LINK_SIGNIFICANT, '', TRUE, $side_of_link);
393  foreach ($links as $link) {
394  $existing_links[] = $link['linkid'];
395  }
396  } else if ($this->attr('delete_linkid') > 0 && $can_safe_trash) {
397  $existing_links[] = $this->attr('delete_linkid');
398  }//end if
399 
400  log_dump($existing_links);
401 
402  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
403  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
404 
405  if (!is_null($target_asset)) {
406  // if moving to the trash, and it is not safe to do so, throw an error
407  $trash_folder = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('trash_folder');
408  if ($major->id == $trash_folder->id && !$can_safe_trash) {
409  trigger_localised_error('CRON0051', E_USER_WARNING, $minor->id);
410  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
411  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
412  return $failed_ret_val;
413  }
414 
415  $link_info = $this->attr('link_info');
416  if (!isset($link_info['value'])) {
417  $link_info['value'] = '';
418  }
419  if (!isset($link_info['sort_order'])) {
420  $link_info['sort_order'] = NULL;
421  }
422  if (!isset($link_info['is_dependant'])) {
423  $link_info['is_dependant'] = '0';
424  }
425  if (!isset($link_info['is_exclusive'])) {
426  $link_info['is_exclusive'] = '0';
427  }
428 
429  $linkid = $major->createLink($minor,
430  $link_info['link_type'],
431  $link_info['value'],
432  $link_info['sort_order'],
433  $link_info['is_dependant'],
434  $link_info['is_exclusive']
435  );
436 
437  $create_ok = ($linkid > 0);
438 
439  if (!$create_ok) {
440  trigger_localised_error('CRON0004', E_USER_WARNING, $major->name, $major->id);
441  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
442  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
443  return $failed_ret_val;
444  }
445 
446  }//end if
447 
448  // Now delete the previous links
449  $delete_link_success = TRUE;
450  foreach ($existing_links as $linkid) {
451  if (!$delete_link_success = $this->_execDeleteLink($linkid)) {
452  break;
453  }//end if
454  }
455  if (!$delete_link_success) {
456  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
457  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
458  return $failed_ret_val;
459  }
460 
461  //update lookups for all assets involved
462  if(!empty($minor)){
463  $this->_tmp['_update_lookups_assets'][] = $minor->id;
464  }
465  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
466 
467  $vars = Array('assetids' => $this->_tmp['_update_lookups_assets']);
468  $lookup_errors = $hh->freestyleHipo('hipo_job_update_lookups', $vars);
469  if (!empty($lookup_errors)) {
470  trigger_localised_error('CRON0008', E_USER_WARNING, $main_asset->name, $main_asset->id);
471  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
472  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
473  return $failed_ret_val;
474  }
475 
476  $msg = "Successful in \n".$desc;
477  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
478  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
479 
480  // all OK, and we can be removed because we have done our one off task
481  return SQ_CRON_JOB_COMPLETED | SQ_CRON_JOB_REMOVE;
482 
483  }//end _exec()
484 
485 
494  protected function _execDeleteLink($linkid)
495  {
496  $delete_ok = FALSE;
497  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkById($linkid);
498 
499  if (!empty($link)) {
500  $old_major = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['majorid'], $link['major_type_code']);
501  //keep all minor assets which must need a lookup update later
502  $minor = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
503  $this->_tmp['_update_lookups_assets'][] = $minor->id;
504  if (!is_null($old_major) && $GLOBALS['SQ_SYSTEM']->am->acquireLock($old_major->id, 'links')) {
505  $delete_ok = $old_major->deleteLink($linkid, TRUE);
506  }
507  }
508 
509  if (!$delete_ok) {
510  trigger_localised_error('CRON0007', E_USER_WARNING, $linkid);
511  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
512  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
513  return FALSE;
514  }
515  return TRUE;
516 
517  }//end _execDeleteLink()
518 
519 
531  public static function &getActiveJobs(Asset $asset, $reverse_mode = FALSE)
532  {
533  $cron_mgr = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cron_manager');
534  if (is_null($cron_mgr)) {
535  $blank = Array();
536  return $blank;
537  }
538 
539  // get all active future lineage jobs
540  $all_jobs = $cron_mgr->getJobs(strtolower(__CLASS__), FALSE);
541 
542  $dates = Array();
543  for ($i = 0, $total = count($all_jobs); $i < $total; $i++) {
544  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($all_jobs[$i]->id, SQ_LINK_NOTICE, 'asset', FALSE, $reverse_mode ? 'major_asset' : 'minor_asset');
545  if (!empty($link) && $link['minorid'] == $asset->id) {
546  $dates[$i] = $all_jobs[$i]->attr('when');
547  }
548 
549  }//end for
550 
551  asort($dates, SORT_STRING);
552  $assets_jobs = Array();
553 
554  foreach ($dates as $i => $date) {
555  $assets_jobs[] = $all_jobs[$i];
556  }//end for
557 
558  return $assets_jobs;
559 
560  }//end getActiveJobs()
561 
562 
572  protected function _canSafeTrash ($minor, $exclude_self = FALSE) {
573  $can_safe_trash = TRUE;
574  if(!$exclude_self){
575  // safe trash is enabled, and asset is LIVE
576  if ($minor->status >= SQ_STATUS_LIVE ) {
577  $can_safe_trash = FALSE;
578  }
579  // safe trash is enabled, and there are notice link(s) to other assets
580  $affected_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($minor->id, SQ_LINK_TYPE_3 + SQ_LINK_NOTICE, '', TRUE, 'minor');
581  foreach ($affected_links as $info) {
582  // make sure that we are not treating notice link to this future cron job as problematic link
583  if ($info['major_type_code'] != $this->type()) {
584  $can_safe_trash = FALSE;
585  break;
586  }
587  }
588  }
589 
590  // check the same thing for all children
591  $ret_val = $GLOBALS['SQ_SYSTEM']->am->generateGetChildrenQuery($minor, '', TRUE, FALSE);
592  $children = $ret_val['sql_array'];
593  $bind_vars = $ret_val['bind_vars'];
594 
595  if (!empty($children)) {
596  // modify the selection so that we only get 1 column
597  $children['select'] = '(SELECT DISTINCT l.minorid';
598  if (isset($children['union_select'])) {
599  $children['union_select'] = 'UNION ALL SELECT sl.minorid';
600  }
601 
602  $sql = 'SELECT
603  majorid, minorid, name, linkid, status, link_type
604  FROM
605  '.SQ_TABLE_RUNNING_PREFIX.'ast_lnk lnk
606  INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast ast ON (ast.assetid = lnk.minorid)
607  WHERE
608  (
609  (link_type = :link_type_3 OR link_type = :link_notice) OR
610  (status >= :status_live)
611  ) AND
612  assetid IN ('.implode(' ', $children).')';
613 
614  try {
615  $query = MatrixDAL::preparePdoQuery($sql);
616  foreach ($bind_vars as $bind_var => $bind_value) {
617  MatrixDAL::bindValueToPdo($query, $bind_var, $bind_value);
618  }
619  MatrixDAL::bindValueToPdo($query, 'link_type_3', SQ_LINK_TYPE_3);
620  MatrixDAL::bindValueToPdo($query, 'link_notice', SQ_LINK_NOTICE);
621  MatrixDAL::bindValueToPdo($query, 'status_live', SQ_STATUS_LIVE);
622  $result = MatrixDAL::executePdoAll($query);
623  } catch (DALException $e) {
624  throw new Exception ('Unable to check if asset "'.$minor->name.'" (#'.$minor->id.') can be safe-trashed due to database error: '.$e->getMessage());
625  }
626  if (!empty($result)) {
627  $can_safe_trash = FALSE;
628  }
629  }
630  return $can_safe_trash;
631  }//end _canSafeTrash()
632 
633 
634 }//end class
635 
636 ?>