18 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
47 var $_assets = Array();
63 var $_system_assetids = Array();
70 var $_attributes = Array();
77 var $_get_asset_history = Array();
89 require_once SQ_INCLUDE_PATH.
'/asset_cache.inc';
91 $this->_asset_cache->setSizeRules((php_sapi_name() ==
'cli') ? SQ_CONF_ASSET_CACHE_SIZE_CLI : SQ_CONF_ASSET_CACHE_SIZE_WEB);
107 $this->_asset_types = Array();
109 if (is_file(SQ_DATA_PATH.
'/private/db/asset_types.inc')) {
110 include(SQ_DATA_PATH.
'/private/db/asset_types.inc');
111 $this->_asset_types = $asset_types;
115 if (!is_file(SQ_DATA_PATH.
'/private/db/table_columns.inc')) {
138 $asset_types = Array();
141 $sql =
'SELECT type_code, version, name, instantiable, allowed_access, parent_type, dir, customisation, description, lvl
145 if (!is_null($instantiable)) {
146 $where .=
' WHERE instantiable = '.MatrixDAL::quote((
int)$instantiable);
148 if ($non_system_access) {
149 $where .= (($where) ?
' AND' :
' WHERE').
' allowed_access != '.
MatrixDAL::quote(
'system');
153 foreach ($rows as $row) {
154 $asset_types[$row[
'type_code']] = $row;
175 $sql =
'SELECT type_code, version, name, instantiable, allowed_access, parent_type, dir, customisation, description, lvl
177 WHERE type_code = :type_code';
183 }
catch (Exception $e) {
184 throw new Exception(
'Unable to get information for type code "'.$type_code.
'" due to database error: '.$e->getMessage());
187 if (empty($result)) {
188 trigger_localised_error(
'SYS0085', E_USER_WARNING, $type_code);
191 $this->_asset_types[$result[0][
'type_code']] = $result[0];
194 $parents = Array($type_code);
195 $tmp_type_code = $type_code;
196 while ($this->_asset_types[$tmp_type_code][
'parent_type'] !=
'asset') {
198 assert_isset($this->_asset_types[$this->_asset_types[$tmp_type_code][
'parent_type']],
'Unable to get the parent of asset type "'.$this->_asset_types[$tmp_type_code][
'parent_type'].
'" as this asset is not installed');
200 $tmp_type_code = $this->_asset_types[$tmp_type_code][
'parent_type'];
201 $parents[] = $tmp_type_code;
203 $parents[] =
'asset';
205 $sql =
'SELECT inhd_type_code
207 WHERE type_code = :type_code';
212 }
catch (Exception $e) {
213 throw new Exception(
'Unable to get inheritance information for type code "'.$type_code.
'" due to database error: '.$e->getMessage());
216 $inserts = array_diff($parents, $db_parents);
217 $deletes = array_diff($db_parents, $parents);
218 $updates = array_intersect($parents, $db_parents);
220 $type_code_level = (int) $this->
getTypeInfo($type_code,
'lvl');
222 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
224 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
226 foreach ($inserts as $inherited_type_code) {
227 $inherited_type_code_level = ($inherited_type_code ==
'asset') ? 0 : (
int) $this->
getTypeInfo($inherited_type_code,
'lvl');
228 $sql =
'INSERT INTO sq_ast_typ_inhd
229 (inhd_type_code, type_code, inhd_type_code_lvl, type_code_lvl)
231 (:inhd_type_code, :type_code, :inhd_lvl, :lvl)';
240 }
catch (Exception $e) {
241 throw new Exception(
'Unable to insert inheritance information for type code "'.$type_code.
'" due to database error: '.$e->getMessage());
245 foreach ($deletes as $inherited_type_code) {
249 inhd_type_code = :inhd_type_code
250 AND type_code = :type_code';
257 }
catch (Exception $e) {
258 throw new Exception(
'Unable to delete inheritance information for type code "'.$type_code.
'" due to database error: '.$e->getMessage());
262 foreach ($updates as $inherited_type_code) {
263 $inherited_type_code_level = ($inherited_type_code ==
'asset') ? 0 : (
int) $this->
getTypeInfo($inherited_type_code,
'lvl');
267 inhd_type_code_lvl = :inhd_lvl,
270 inhd_type_code = :inhd_type_code
271 AND type_code = :type_code';
280 }
catch (Exception $e) {
281 throw new Exception(
'Unable to update inheritance information for type code "'.$type_code.
'" due to database error: '.$e->getMessage());
285 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
286 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
301 return isset($this->_asset_types[$type_code]);
314 return array_keys($this->_asset_types);
333 $field = trim($field);
336 if (!is_file(SQ_DATA_PATH.
'/private/db/asset_types.inc')) {
338 if (empty($type_code)) {
349 if (is_array($type_code)) {
350 foreach ($type_code as $key => $asset_type) {
353 $type_code_cond =
'IN ('.implode(
', ', $type_code).
')';
355 $type_code_cond =
' = '.MatrixDAL::quote($type_code);
360 $field_list =
'type_code, version, name, description, instantiable, allowed_access, parent_type, lvl, dir, customisation';
362 $field_list =
'type_code, '.$field;
370 type_code '.$type_code_cond;
375 }
catch (Exception $e) {
376 if (is_array($type_code)) {
377 throw new Exception(
'Unable to get type info for multiple type codes due to database error: '.$e->getMessage());
379 throw new Exception(
'Unable to get type info for type code "'.$type_code.
'" due to database error: '.$e->getMessage());
383 if (!is_array($type_code) && !empty($field)) {
384 return $result[$type_code][0][$field];
387 if (is_array($type_code)) {
390 return $result[$type_code][0];
395 if (is_array($type_code)) {
397 foreach ($type_code as $type) {
398 if (!isset($this->_asset_types[$type])) {
399 trigger_localised_error(
'SYS0091', E_USER_WARNING, $type);
403 $result[$type] = $this->_asset_types[$type];
405 if (!isset($this->_asset_types[$type][$field])) {
406 trigger_localised_error(
'SYS0185', E_USER_WARNING, $field);
409 $result[$type] = $this->_asset_types[$type][$field];
414 if (!isset($this->_asset_types[$type_code])) {
415 trigger_localised_error(
'SYS0091', E_USER_WARNING, $type_code);
416 return (empty($field)) ? Array() : NULL;
419 return $this->_asset_types[$type_code];
421 if (!isset($this->_asset_types[$type_code][$field])) {
422 trigger_localised_error(
'SYS0185', E_USER_WARNING, $field);
425 return $this->_asset_types[$type_code][$field];
445 if (empty($base_type_code)) $base_type_code =
'asset';
447 $type_codes = Array();
448 $allowed_access = trim($allowed_access);
449 if (!empty($allowed_access)) {
452 'allowed_access' => $allowed_access,
455 }
catch (Exception $e) {
456 throw new Exception(
'Failed to get type code with allowed access due to database error: '. $e->getMessage());
459 $type_codes = array_keys($this->_asset_types);
462 $offspring = Array();
463 foreach ($type_codes as $type_code) {
464 if (is_array($type_code)) {
465 $type_code = $type_code[
'type_code'];
468 $parent = $this->_asset_types[$type_code][
'parent_type'];
469 if (!isset($offspring[$parent])) {
470 $offspring[$parent] = Array();
472 $offspring[$parent][] = $type_code;
493 if (empty($offspring[$base_type_code]))
return Array();
495 for ($i = 0; $i < count($offspring[$base_type_code]); $i++) {
496 $type = $offspring[$base_type_code][$i];
498 'name' => $this->_asset_types[$type][
'name'],
519 if (!is_array($assetids)) {
520 $assetids = Array($assetids);
522 assert_type($type_code,
'array');
523 if (empty($assetids))
return Array();
528 $shadowids = Array();
529 $normalids = Array();
530 $shadow_results = Array();
533 for ($i = 0; $i < count($assetids); $i++) {
534 $id_parts = explode(
':', $assetids[$i]);
536 if (isset($id_parts[1])) {
537 $shadowids[$id_parts[0]][] = $assetids[$i];
539 $normalids[] = $assetids[$i];
544 $assetids = $normalids;
547 if (!empty($shadowids)) {
548 $shadow_result = Array();
551 foreach ($shadowids as $assetid => $shadows) {
553 if (method_exists($asset,
'getAssetInfo')) {
554 $shadow_results += $asset->getAssetTypeInfo($shadows, $type_code, $strict_type_code);
560 if (empty($assetids))
return $shadow_results;
562 for (reset($assetids); NULL !== ($k = key($assetids)); next($assetids)) {
565 $where .=
'a.assetid IN ('.implode(
', ', $assetids).
')';
567 if (!empty($type_code)) {
569 $type_code_cond =
'';
570 if (is_array($type_code)) {
571 for ($i = 0; $i < count($type_code); $i++) {
574 $type_code_cond =
'IN ('.implode(
', ', $type_code).
')';
576 $type_code_cond =
'= '.MatrixDAL::quote($type_code);
579 if ($strict_type_code) {
580 $where .=
' AND a.type_code '.$type_code_cond;
582 $where .=
' AND a.type_code IN (
585 WHERE inhd_type_code '.$type_code_cond.
'
590 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
591 $sql =
'SELECT a.assetid, at.inhd_type_code
592 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast a INNER JOIN sq_ast_typ_inhd at ON a.type_code = at.type_code
593 '.$where.
' ORDER BY a.assetid ASC, at.inhd_type_code_lvl DESC';
597 $result += $shadow_results;
599 }
catch (Exception $e) {
600 throw new Exception(
'Unable to get asset type info due to database error: '.$e->getMessage());
619 $error_msg =
'Asset "'.$type_code.
'" is not installed on the system, unable to include its source file';
620 $type_code = strtolower($type_code);
621 assert_isset_array_index($this->_asset_types, $type_code, $error_msg);
624 if (isset($this->_asset_types[$type_code][
'included']) && $this->_asset_types[$type_code][
'included']) {
628 require_once SQ_SYSTEM_ROOT.
'/'.$this->_asset_types[$type_code][
'dir'].
'/'.$type_code.
'.inc';
629 if ($with_edit_fns) {
630 require_once SQ_SYSTEM_ROOT.
'/'.$this->_asset_types[$type_code][
'dir'].
'/'.$type_code.
'_edit_fns.inc';
634 $GLOBALS[
'SQ_SYSTEM']->lm->includeAssetStrings($type_code);
636 $GLOBALS[
'SQ_SYSTEM']->lm->includeAssetStrings($type_parent);
639 $this->_asset_types[$type_code][
'included'] = TRUE;
658 if ($type_code ==
'asset')
return Array();
659 assert_isset_array_index($this->_asset_types, $type_code,
'Asset Type "'.$type_code.
'" is not installed on the system');
661 if ($query_db || !isset($this->_asset_types[$type_code][
'ancestor_types'])) {
669 type_code = :type_code
670 AND inhd_type_code <> type_code
671 '.(($include_asset) ?
'' :
' AND inhd_type_code <> :asset_type_code').
'
672 ORDER BY inhd_type_code_lvl DESC';
677 if (!$include_asset) {
681 }
catch (Exception $e) {
682 throw new Exception(
'Unable to load type descendants of asset type "'.$type_code.
'" due to database error: '.$e->getMessage());
688 $res = $this->_asset_types[$type_code][
'ancestor_types'];
689 if ($include_asset) $res[] =
'asset';
709 if (!is_array($type_code)) {
710 $type_code = Array($type_code);
713 for (reset($type_code); NULL !== ($i = key($type_code)); next($type_code)) {
714 if ($type_code[$i] !=
'asset') {
715 assert_isset_array_index($this->_asset_types, $type_code[$i],
'Asset Type "'.$type_code[$i].
'" is not installed on the system');
721 'type_codes' => $type_code,
722 'include_passed' => $include_passed,
726 }
catch (Exception $e) {
727 throw new Exception(
'Unable to load type descendants of asset type "'.$type_code.
'" due to database error: '.$e->getMessage());
748 return in_array(strtolower($type_code1), $decendants);
765 return in_array($type_code1, $ancestors);
780 $file = SQ_ATTRIBUTES_PATH.
'/'.$attr_type.
'/'.$attr_type.
'.inc';
781 if (!file_exists($file))
return FALSE;
783 return class_exists(
'Asset_Attribute_'.$attr_type);
801 assert_type($attrids,
'array');
802 if (empty($attrids))
return Array();
806 for ($i = 0; $i < count($attrids); $i++) {
809 $where =
'a.attrid IN ('.implode(
', ', $attrids).
')';
810 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
812 $sql =
'SELECT * FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_attr a '.$where.
' ORDER BY a.attrid';
817 }
catch (Exception $e) {
818 throw new Exception(
'Unable to fetch attribute info due to database error: '.$e->getMessage());
821 $return_result = Array();
822 foreach (array_values($result) as $row) {
823 foreach ($row as $name => $value) {
824 $return_result[$row[
'attrid']][$name] = $value;
828 return $return_result;
847 if (!isset($this->_attributes[$attrid]) || !is_object($this->_attributes[$attrid][
'object'])) {
849 $this->_attributes[$attrid] = Array();
850 $this->_attributes[$attrid][
'object'] = NULL;
851 $this->_attributes[$attrid][
'count'] = 0;
853 include_once SQ_INCLUDE_PATH.
'/asset_attribute.inc';
855 $this->_attributes[$attrid][
'object'] = $base_attr->loadAttribute($attrid);
857 if (empty($this->_attributes[$attrid][
'object']->
id)) {
858 $this->_attributes[$attrid][
'object'] = NULL;
863 $this->_attributes[$attrid][
'count']++;
864 return $this->_attributes[$attrid][
'object'];
880 if (!is_string($type_code))
return Array();
883 require_once SQ_INCLUDE_PATH.
'/asset_attribute.inc';
885 $sql =
'SELECT '.implode(
', ', $details).
' FROM sq_ast_attr
886 WHERE type_code = :type_code';
892 if (count($details) > 1) {
895 foreach ($result_x as $key => $row) {
896 $result[$key] = $row[0];
901 }
catch (Exception $e) {
902 throw new Exception(
'Unable to get asset info due to database error: '.$e->getMessage());
934 if (empty($assetids))
return Array();
937 $shadowids = Array();
938 $normalids = Array();
939 foreach ($assetids as $one_id) {
940 $id_parts = explode(
':', $one_id);
941 if (isset($id_parts[1])) {
942 $shadowids[$id_parts[0]][] = $one_id;
944 $normalids[] = $one_id;
949 $assetids = $normalids;
952 $shadow_results = Array();
953 foreach ($shadowids as $assetid => $shadows) {
954 $asset = $this->
getAsset($assetid,
'', TRUE);
955 if (!is_null($asset) && method_exists($asset,
'getAttributeValuesByName')) {
956 $shadow_results += $asset->getAttributeValuesByName($attr_name, $asset_type, $shadows, $contextid);
961 if (empty($assetids))
return $shadow_results;
963 if ($contextid === NULL) {
964 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
968 $in =
'assetid IN (';
970 for ($i = 0; $i < count($assetids); $i++) {
971 $in .=
MatrixDAL::quote( (
string) $assetids[$i] ).(($i == count($assetids) - 1) ?
')' :
',');
975 $sql =
'SELECT a.assetid, at.default_val
976 FROM sq_ast a, sq_ast_attr at
977 WHERE a.type_code = at.type_code
978 AND at.name = :attr_name
979 AND ((at.type_code = :asset_type) OR (at.owning_type_code = :asset_type))
986 }
catch (Exception $e) {
987 throw new Exception(
'Unable to get default attribute values due to database error: '.$e->getMessage());
991 foreach ($res as $assetid => $val_info) {
992 if (isset($val_info[0][
'default_val'])) {
993 $res[$assetid] = $val_info[0][
'default_val'];
995 else if (isset($val_info[0]) && is_array($val_info[0]) && array_key_exists(
'default_val',$val_info[0])){
1001 $sub_sql =
'SELECT attrid FROM sq_ast_attr WHERE name = :attr_name';
1002 if ($asset_type !=
'asset') {
1003 $sub_sql .=
' AND (type_code = :asset_type OR owning_type_code = :asset_type_1)';
1007 $bind_vars = Array();
1008 if ($dbtype ===
'pgsql') {
1009 if (count($assetids) <= 10) {
1013 $sql =
'SELECT assetid, custom_val FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_attr_val';
1014 $where =
'attrid IN ('.$sub_sql.
') AND '.$in;
1015 $where .=
' AND contextid = :contextid';
1016 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where);
1018 $bind_vars[
'contextid'] = $contextid;
1034 $sql1 =
'SELECT assetid, custom_val
1035 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_attr_val';
1036 $where1 =
'attrid IN ('.$sub_sql.
') ';
1037 $where1 .=
' AND contextid = :contextid_1';
1038 $where1 = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where1);
1040 $sql2 =
'SELECT assetid, custom_val
1041 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_attr_val';
1043 $where2 .=
' AND contextid = :contextid_2';
1044 $where2 = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where2);
1046 $sql = $sql1 . $where1 .
' INTERSECT ' . $sql2 . $where2;
1047 $bind_vars[
'contextid_1'] = $contextid;
1048 $bind_vars[
'contextid_2'] = $contextid;
1061 if ($dbtype ===
'oci') {
1062 $sql =
'SELECT assetid, custom_val FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_attr_val';
1063 $where =
'attrid IN ('.$sub_sql.
') AND '.$in;
1064 $where .=
' AND contextid = :contextid';
1065 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where);
1067 $bind_vars[
'contextid'] = $contextid;
1070 $bind_vars[
'attr_name'] = $attr_name;
1071 if ($asset_type !==
'asset') {
1072 $bind_vars[
'asset_type'] = $asset_type;
1073 $bind_vars[
'asset_type_1'] = $asset_type;
1078 foreach ($bind_vars as $bind_var => $bind_value) {
1082 }
catch (Exception $e) {
1083 throw new Exception(
'Unable to get customised attribute values for attr "'.$attr_name.
'" and type "'.$asset_type.
'" due to database error: '.$e->getMessage());
1088 foreach ($custom_vals as $assetid => $rowinfo) {
1089 if (isset($rowinfo[0][
'custom_val'])) {
1090 $res[$assetid] = $rowinfo[0][
'custom_val'];
1092 else if (isset($rowinfo[0]) && is_array($rowinfo[0]) && array_key_exists(
'custom_val',$rowinfo[0])){
1093 $res[$assetid] =
'';
1122 if ($contextid === NULL) {
1123 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
1134 $sql =
'SELECT atr.name, atr.attrid, atr.type, COALESCE(v.custom_val, atr.default_val) AS value, atr.is_contextable, v.use_default
1135 FROM (sq_ast_attr atr
1136 LEFT OUTER JOIN (SELECT * FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_attr_val WHERE contextid = :contextid) v
1137 ON (atr.attrid = v.attrid AND v.assetid = :assetid'
1138 .$GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause(
'',
'v',
'AND').
'))
1139 WHERE atr.type_code = :type_code';
1142 $sql =
'SELECT atr.name, atr.attrid, atr.type, atr.default_val AS value, atr.is_contextable, \'1\' as use_default
1143 FROM sq_ast_attr atr
1144 WHERE atr.type_code = :type_code';
1157 if (empty($result)) {
1161 foreach (array_keys($vars) as $name) {
1162 $vars[$name] = $vars[$name][0];
1163 unset($vars[$name][0]);
1168 }
catch (Exception $e) {
1169 throw new Exception(
'Unable to load variables of asset #'.$assetid.
' ('.$type_code.
') due to database error: '.$e->getMessage());
1192 function getAsset($assetid, $type_code=
'', $mute_errors=FALSE)
1195 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
1198 if (is_array($assetid)) {
1199 $msg = translate(
'assert_assetid', gettype($assetid),
'');
1200 trigger_exception($msg, FALSE, TRUE);
1205 assert_valid_assetid($assetid);
1206 $asset = $this->_asset_cache->get($contextid.
'\\'.$assetid);
1208 if (empty($asset)) {
1210 $deja_vu = $GLOBALS[
'SQ_SYSTEM']->getDejaVu();
1212 $asset = $deja_vu->recall(SQ_DEJA_VU_ASSET, $assetid);
1213 if (!empty($asset)) {
1214 if ($asset->status & SQ_SC_STATUS_SAFE_EDITING) {
1219 $this->_asset_cache->add($asset, $contextid.
'\\'.$asset->id);
1228 if (!empty($asset)) {
1233 if (!empty($type_code) && $asset->type() != $type_code) {
1234 if (!$mute_errors) {
1235 trigger_localised_error(
'SYS0089', E_USER_WARNING, $assetid, $type_code);
1244 $id_parts = explode(
':', $assetid);
1245 if (isset($id_parts[1])) {
1246 $real_assetid = $id_parts[0];
1247 $bridge = $this->
getAsset($real_assetid,
'', TRUE);
1248 if (is_null($bridge)) {
1252 }
else if (!method_exists($bridge,
'getAsset')) {
1253 trigger_localised_error(
'SYS0203', E_USER_WARNING, $bridge->name);
1255 $asset = $bridge->getAsset($assetid,
'', $mute_errors);
1261 if (empty($type_code)) {
1262 $sql =
'SELECT type_code FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast ';
1263 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause(
'assetid = :assetid');
1269 if (empty($type_code)) {
1270 if (!$mute_errors) {
1271 trigger_localised_error(
'SYS0087', E_USER_WARNING, $assetid);
1274 if (!isset($this->_asset_types[$type_code])) {
1275 if (!$mute_errors) {
1276 trigger_localised_error(
'SYS0091', E_USER_WARNING, $type_code);
1281 $asset = @
new $type_code($assetid);
1283 $asset =
new $type_code($assetid);
1285 if (empty($asset->id)) {
1293 if (isset($asset)) {
1294 $this->_get_asset_history[] = $assetid;
1295 $this->_asset_cache->add($asset, $contextid.
'\\'.$asset->id);
1297 $deja_vu = $GLOBALS[
'SQ_SYSTEM']->getDejaVu();
1298 if ($deja_vu && !($asset->status & SQ_SC_STATUS_SAFE_EDITING)) {
1299 $deja_vu->remember(SQ_DEJA_VU_ASSET, $asset->id, $asset);
1322 $shadow_asset_ids = Array();
1325 $count = count($assetids);
1327 $is_array = is_array($assetids);
1328 $is_empty = empty($assetids);
1331 if ($is_array && !$is_empty) {
1332 foreach ($assetids as $key => $value) {
1333 assert_valid_assetid($value);
1336 $id_parts = explode(
':', $value);
1337 if (isset($id_parts[1])) {
1338 $shadows[$id_parts[0]][] = $value;
1341 }
else if (!$is_empty) {
1342 assert_valid_assetid($assetids);
1344 $id_parts = explode(
':', $assetids);
1345 if (isset($id_parts[1])) {
1346 $shadows[$id_parts[0]][] = $id_parts[0].
':'.$id_parts[1];
1351 if (!empty($shadows)) {
1352 foreach ($shadows as $shadow_id => $shadow) {
1353 $asset = $this->
getAsset($shadow_id);
1354 if (method_exists($asset,
'assetExists')) {
1355 $ret_val = $asset->assetExists($shadow);
1356 if (is_array($ret_val)) {
1357 $shadow_asset_ids += $ret_val;
1358 }
else if ($ret_val) {
1359 $shadow_asset_ids[] = $shadow;
1367 $sql =
'SELECT assetid
1368 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast ';
1372 if ($is_empty)
return FALSE;
1373 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause(
'assetid = :assetids');
1378 }
catch (Exception $e) {
1379 throw new Exception(
'Unable to determine if asset with assetid: '.$assetids.
' exists due to database error: '.$e->getMessage());
1382 if (!empty($shadow_asset_ids)) {
1383 $shadow_asset_ids[] = $db_assetids;
1385 return ($db_assetids == $assetids);
1390 $existing_asset_ids = Array();
1392 $in =
'assetid IN (';
1394 for ($i=0; $i<count($assetids); $i++) {
1395 $in .=
MatrixDAL::quote( (
string) $assetids[$i] ).(($i == count($assetids) - 1) ?
')' :
',');
1398 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($in);
1401 }
catch (Exception $e) {
1402 throw new Exception(
'Unable to determine if multipled assets exists due to database error: '.$e->getMessage());
1405 foreach ($db_assetids as $db_id) {
1406 $existing_asset_ids[] = $db_id[
'assetid'];
1410 for ($i = 0; $i < count($shadow_asset_ids); $i++) {
1411 $existing_asset_ids[] = $shadow_asset_ids[$i];
1414 return $existing_asset_ids;
1432 if (!is_object($obj) || !($obj instanceof
Asset) || !$obj->id) {
1436 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
1438 if (!$this->_asset_cache->add($obj, $contextid.
'\\'.$obj->id)) {
1439 trigger_localised_error(
'SYS0305', E_USER_ERROR, $obj->id);
1461 if (!is_object($obj) || !($obj instanceof
Asset) || !$obj->id) {
1465 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
1467 $this->_asset_cache->release($contextid.
'\\'.$obj->id);
1469 if (!$this->_asset_cache->remove($contextid.
'\\'.$obj->id, TRUE)) {
1470 trigger_localised_error(
'SYS0306', E_USER_WARNING, $contextid.
'\\'.$obj->id);
1472 if (isset($obj->_tmp)) unset($obj->_tmp);
1489 if (!is_string($name)) {
1490 trigger_localised_error(
'SYS0190', E_USER_WARNING);
1494 if (empty($this->_system_assetids)) {
1498 if (isset($this->_system_assetids[$name])) {
1499 return $this->_system_assetids[$name];
1501 trigger_localised_error(
'SYS0209', E_USER_WARNING, $name);
1516 require_once SQ_INCLUDE_PATH.
'/system_asset_config.inc';
1519 if (!file_exists($sys_asset_cfg->config_file)) {
1521 $system_assets = FALSE;
1523 require $sys_asset_cfg->config_file;
1526 $this->_system_assetids = $system_assets;
1539 $this->_system_assetids = Array();
1557 if (empty($this->_system_assetids)) {
1561 return isset($this->_system_assetids[$asset_type]);
1577 if (is_null($asset_type) || is_null($assetid)) {
1581 $this->_system_assetids[$asset_type] = $assetid;
1601 if ($assetid !== FALSE) {
1602 $asset = $this->
getAsset($assetid, $name, $mute_errors);
1625 require SQ_DATA_PATH.
'/private/conf/system_assets.inc';
1626 $system_asset_ids = array_values($system_assets);
1627 if (in_array($asset->id, $system_asset_ids)) {
1635 foreach ($parents as $parentid) {
1636 if (in_array($parentid, $system_asset_ids)) {
1660 function getAssetInfo($assetids, $type_code=Array(), $strict_type_code=TRUE, $field=
'')
1662 $shadow_results = Array();
1663 if (!is_array($assetids)) {
1664 $assetids = Array($assetids);
1666 if (empty($assetids))
return Array();
1668 $bind_vars = Array();
1671 $shadowids = Array();
1672 $normalids = Array();
1673 $shadow_results = Array();
1676 foreach ($assetids as $one_id) {
1677 $id_parts = explode(
':', $one_id);
1679 if (isset($id_parts[1])) {
1680 $shadowids[$id_parts[0]][] = $one_id;
1682 $normalids[] = $one_id;
1687 $assetids = $normalids;
1690 if (!empty($shadowids)) {
1691 $shadow_result = Array();
1694 foreach ($shadowids as $assetid => $shadows) {
1695 $asset = $this->
getAsset($assetid,
'', TRUE);
1696 if ($asset && method_exists($asset,
'getAssetInfo')) {
1697 $shadow_results += $asset->getAssetInfo($shadows, $type_code, $strict_type_code, $field);
1703 if (empty($assetids))
return $shadow_results;
1707 if (!empty($field)) {
1708 if (empty($this->_tmp[
'sq_tables'])) {
1709 require SQ_DATA_PATH.
'/private/db/table_columns.inc';
1710 $this->_tmp[
'sq_tables'] = $tables;
1715 if (!in_array($field, $this->_tmp[
'sq_tables'][
'ast'][
'columns'])) {
1716 trigger_localised_error(
'SYS0185', E_USER_WARNING, $field);
1721 for ($i = 0; $i < count($assetids); $i++) {
1726 $in_clauses = Array();
1727 foreach (array_chunk($assetids, 999) as $chunk) {
1728 $in_clauses[] =
' a.assetid IN ('.implode(
', ', $chunk).
')';
1730 $where =
'('.implode(
' OR ', $in_clauses).
')';
1732 if (!empty($type_code)) {
1733 $type_code_cond =
'';
1734 $type_query_str = Array();
1735 if (is_array($type_code)) {
1736 for ($i = 0; $i < count($type_code); $i++) {
1737 $bind_vars[
'type_code_'.$i] = $type_code[$i];
1738 $type_query_str[] =
':type_code_'.$i;
1740 $type_code_cond =
'IN ('.implode(
', ', $type_query_str).
')';
1742 $type_code_cond =
'= :type_code';
1743 $bind_vars[
'type_code'] = $type_code;
1746 if ($strict_type_code) {
1747 $where .=
' AND a.type_code '.$type_code_cond;
1749 $where .=
' AND a.type_code IN (
1751 FROM sq_ast_typ_inhd
1752 WHERE inhd_type_code '.$type_code_cond.
'
1757 if (empty($field)) {
1761 if (empty($this->_tmp[
'sq_tables'])) {
1762 require SQ_DATA_PATH.
'/private/db/table_columns.inc';
1763 $this->_tmp[
'sq_tables'] = $tables;
1765 $tables = $this->_tmp[
'sq_tables'];
1767 unset($tables[
'ast'][
'columns'][array_search(
'assetid', $tables[
'ast'][
'columns'])]);
1768 $col_string = implode(
', ', $tables[
'ast'][
'columns']);
1772 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
1773 $sql =
'SELECT assetid, '.((empty($field)) ? $col_string : $field).
'
1774 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast a
1776 ORDER BY a.assetid';
1780 foreach ($bind_vars as $bind_var => $bind_value) {
1786 foreach ($result_x as $key => $row) {
1794 if (!empty($field) && (strcmp($field,
'assetid') == 0)) {
1795 $result[$key] = $key;
1798 $result[$key] = (empty($field)) ? $row[0] : $row[0][$field];
1803 }
catch (Exception $e) {
1804 throw new Exception(
'Unable to get asset info due to database error: '.$e->getMessage());
1808 $result += $shadow_results;
1823 if (!isset($this->_tmp[
'asset_info_fields'])) {
1824 require SQ_DATA_PATH.
'/private/db/table_columns.inc';
1825 $this->_tmp[
'asset_info_fields'] = Array();
1826 foreach ($tables[
'ast'][
'columns'] as $col) {
1827 $this->_tmp[
'asset_info_fields'][$col] = translate(
'asset_field_'.$col);
1831 return $this->_tmp[
'asset_info_fields'];
1851 if (!is_string($type_code))
return Array();
1855 $where =
'type_code = :type_code';
1857 $where =
'type_code IN (
1859 FROM sq_ast_typ_inhd
1860 WHERE inhd_type_code = :type_code
1864 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where);
1865 $sql =
'SELECT assetid'.(($include_type) ?
', type_code' :
'').
'
1866 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast '.$where;
1871 if ($include_type) {
1874 foreach ($result_x as $key => $row) {
1875 $result[$key] = $row[0];
1880 }
catch (Exception $e) {
1908 $contents = Array();
1910 foreach ($children as $child_id) {
1911 $child = $this->
getAsset($child_id);
1917 for ($i = 0; $i < count($dependants_children); $i++) {
1918 if (in_array($dependants_children[$i], $children)) {
1923 $child_content = $child->getContent();
1925 if (!empty($child_content)) {
1926 $contents[$child_id] = $child->getContent();
1932 return empty($contents) ? FALSE : $contents;
1949 $asset = $this->
getAsset($assetid);
1951 if (is_null($asset))
return FALSE;
1953 $asset->setContent($content);
2004 function _cloneAsset(&$source, &$link, &$clone_map, $components, $cloning_dependent=FALSE)
2006 if (!empty($link)) {
2008 assert_isset_array_index($link,
'asset',
'Cannot clone asset without an asset to link to');
2009 assert_isset_array_index($link,
'link_type',
'Cannot clone asset without a link type');
2010 assert_not_empty(($link[
'link_type'] & SQ_SC_LINK_SIGNIFICANT),
'Cannot clone asset with an insignificant link type');
2014 if (!$source->id)
return $null;
2015 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
2017 foreach ($lock as $lock_type => $lock_info) {
2018 if (empty($lock_info)) {
2019 trigger_localised_error(
'SYS0266', E_USER_WARNING, $source->id, $lock_type);
2024 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
2026 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
2031 $userid = $GLOBALS[
'SQ_SYSTEM']->currentUserId();
2033 $initial_version =
'0.0.0';
2037 'date_value' => ts_iso8601(time()),
2041 'assetid' => $assetid,
2042 'version' => $initial_version,
2043 'type_code' => $source->type(),
2044 'name' => $source->name.
' - clone',
2045 'short_name' => $source->short_name.
' - clone',
2046 'status' => SQ_STATUS_UNDER_CONSTRUCTION,
2047 'created' => $last_updated,
2048 'created_userid' => $userid,
2049 'published' => NULL,
2050 'published_userid' => NULL,
2051 'updated' => $last_updated,
2052 'updated_userid' => $userid,
2053 'status_changed' => NULL,
2054 'status_changed_userid' => NULL,
2057 }
catch (Exception $e) {
2058 throw new Exception(
'Failed to create cloned asset due to database error: '.$e->getMessage());
2061 $clone = $this->
getAsset($assetid, $source->type());
2062 if (is_null($clone)) {
2063 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2064 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2068 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
2070 if (!$this->
acquireLock($clone->id,
'all', $source->id)) {
2071 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2072 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2077 $parent_components = Array(
2085 if (!$cloning_dependent) {
2086 $parent_components[] =
'content_tags';
2098 if (!empty($link)) {
2099 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_INTEGRITY)) {
2100 $this->_tmp[__CLASS__.
'_in_create_cascading'] = TRUE;
2101 $GLOBALS[
'SQ_SYSTEM']->setRunLevel($GLOBALS[
'SQ_SYSTEM']->getRunLevel() & SQ_RUN_LEVEL_FORCED);
2104 $nonlink_parent_components = $parent_components;
2105 foreach ($nonlink_parent_components as $idx => $component) {
2106 if ($component ==
'content_tags') {
2107 unset($nonlink_parent_components[$idx]);
2111 if (!$link[
'asset']->cloneComponents($clone, $nonlink_parent_components)) {
2112 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2113 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2115 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
2119 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
2120 unset($this->_tmp[__CLASS__.
'_in_create_cascading']);
2128 $nonlink_components = $components;
2129 foreach ($nonlink_components as $idx => $component) {
2130 if ($component ==
'content_tags') {
2131 unset($nonlink_components[$idx]);
2134 if (!$source->cloneComponents($clone, $nonlink_components, TRUE)) {
2135 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2136 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2143 $clone = $this->
_cloneLink($clone, $link, $lock, $source);
2144 if (is_null($clone)) {
2145 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2146 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2147 return $clone_result;
2152 $clone->setForceSecure($source->force_secure);
2155 if (!$source->cloneLinks($clone)) {
2156 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2157 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2168 if (!empty($link)) {
2169 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_INTEGRITY)) {
2170 $this->_tmp[__CLASS__.
'_in_create_cascading'] = TRUE;
2171 $GLOBALS[
'SQ_SYSTEM']->setRunLevel($GLOBALS[
'SQ_SYSTEM']->getRunLevel() & SQ_RUN_LEVEL_FORCED);
2174 $link_parent_components = (in_array(
'content_tags', $parent_components) ? Array(
'content_tags') : Array());
2176 if (!empty($link_parent_components) && !$link[
'asset']->cloneComponents($clone, $link_parent_components)) {
2177 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2178 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2180 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
2184 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
2185 unset($this->_tmp[__CLASS__.
'_in_create_cascading']);
2190 $link_components = $components;
2191 foreach ($link_components as $idx => $component) {
2192 if ($component !=
'content_tags') {
2193 unset($link_components[$idx]);
2196 if (!empty($link_components) && !$source->cloneComponents($clone, $link_components, TRUE)) {
2197 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2198 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2205 $clone_map[$source->id] = $clone->id;
2206 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
2207 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2230 if (!empty($link)) {
2232 if (!isset($link[
'value'])) $link[
'value'] =
'';
2233 if (!isset($link[
'sort_order'])) {
2234 $link[
'sort_order'] = -1;
2236 if (!isset($link[
'is_dependant'])) {
2237 $link[
'is_dependant'] = 0;
2239 if (!isset($link[
'is_exclusive'])) {
2240 $link[
'is_exclusive'] = 0;
2243 $linkid = $link[
'asset']->createLink($clone, $link[
'link_type'], $link[
'value'], $link[
'sort_order'], $link[
'is_dependant'], $link[
'is_exclusive']);
2244 if (empty($linkid))
return $null;
2297 function &
cloneAsset(&$source, &$link, &$clone_map, $components, $clone_dependents=TRUE, $cloning_dependent=FALSE)
2301 $id_parts = explode(
':', $source->id);
2302 if (isset($id_parts[1]))
return $null;
2305 if (!$source->canClone()) {
2306 trigger_localised_error(
'SYS0070', E_USER_WARNING, $source->type());
2309 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
2310 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
2312 $clone = $this->
_cloneAsset($source, $link, $clone_map, $components, $cloning_dependent);
2313 if (is_null($clone)) {
2314 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2315 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2320 if ($clone_dependents) {
2322 $dependent_links = $this->
getLinks($source->id, SQ_SC_LINK_SIGNIFICANT,
'', TRUE,
'major', NULL, 1);
2324 if (!empty($dependent_links)) {
2325 $create_link = Array(
2327 'link_type' => NULL,
2330 'is_dependant' =>
'1',
2331 'is_exclusive' =>
'0',
2334 foreach ($dependent_links as $data) {
2337 if (isset($clone_map[$data[
'minorid']])) {
2339 $cloned_child = $this->
getAsset($clone_map[$data[
'minorid']], $data[
'minor_type_code']);
2340 if (is_null($cloned_child)) {
2341 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2342 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2346 $linkid = $clone->createLink($cloned_child, $data[
'link_type'], $data[
'value'], $data[
'sort_order'],
'1', $data[
'is_exclusive']);
2348 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2349 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2355 $child = $this->
getAsset($data[
'minorid'], $data[
'minor_type_code']);
2356 if (is_null($child))
continue;
2359 $id_parts = explode(
':', $child->id);
2360 if (isset($id_parts[1]))
continue;
2362 $create_link[
'link_type'] = $data[
'link_type'];
2363 $create_link[
'value'] = $data[
'value'];
2364 $create_link[
'sort_order'] = $data[
'sort_order'];
2365 $create_link[
'is_exclusive'] = $data[
'is_exclusive'];
2366 $new_component = Array();
2368 $cloned_child = $this->
cloneAsset($child, $create_link, $clone_map, $components, $clone_dependents, TRUE);
2370 if (is_null($cloned_child)) {
2371 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2372 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2377 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
2379 $lock = $this->
getLockInfo($cloned_child->id,
'all');
2380 if (!empty($lock)) {
2381 if (!$this->
releaseLock($cloned_child->id,
'all')) {
2382 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2383 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2394 if (!$source->cloneComponentsAdditional($clone, Array(
'all'))) {
2395 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2396 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2403 $sm = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'search_manager');
2405 $sm->reindexAsset($clone, Array(
'all'));
2406 $sm->reindexContents($clone, Array());
2409 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
2410 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2413 $parameter = Array();
2414 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_asset_cloned', $clone, $parameter);
2444 function acquireLock($assetid, $lock_type, $source_assetid=0, $force=FALSE, $expires=0)
2447 if (empty($lock_type) || !is_string($lock_type)) {
2448 trigger_localised_error(
'SYS0074', E_USER_WARNING, $assetid);
2452 $asset = $this->
getAsset($assetid);
2454 if (is_null($asset))
return FALSE;
2458 $orig_lock_type = $lock_type;
2460 $current_locks = $this->
getLockInfo($assetid, $lock_type, TRUE, TRUE);
2461 if (empty($current_locks))
return FALSE;
2463 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
2464 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
2474 if ($force === FALSE) {
2478 $lock_updated = FALSE;
2479 foreach ($current_locks as $lock_type => $lock) {
2481 if (!empty($lock) && $lock[
'userid'] == $GLOBALS[
'SQ_SYSTEM']->currentUserid()) {
2484 if ($this->
updateLock($assetid, $lock_type, $expires)) {
2485 $lock_updated = TRUE;
2493 if ($can_force === NULL) {
2494 $can_force = $asset->canForceablyAcquireLock($orig_lock_type);
2499 if (!empty($lock) && $can_force) {
2508 $ms = $GLOBALS[
'SQ_SYSTEM']->getMessagingService();
2512 $user = $this->
getAsset($lock[
'userid']);
2514 $locked_assetids = Array((
int) $assetid);
2515 foreach ($lock[
'chained_assets'] as $row) {
2516 $locked_assetids[] = $row[
'assetid'];
2519 foreach ($locked_assetids as $locked_assetid) {
2520 $locked_asset = $this->
getAsset($locked_assetid);
2525 'user_name' => $GLOBALS[
'SQ_SYSTEM']->user->name,
2526 'type_code' => $this->getTypeInfo($locked_asset->type(),
'name'),
2527 'lock_type' => ucwords($lock_type),
2528 'asset_name' => $locked_asset->name,
2529 'old_user_name' => $user->name,
2531 $log = $ms->newMessage(Array(),
'asset.locking.forced', $msg_reps);
2532 $log->parameters[
'assetid'] = $locked_asset->id;
2533 $log->parameters[
'former_userid'] = $user->id;
2534 $ms->logMessage($log);
2544 $lock = $this->
getLockInfo($assetid, $lock_type, FALSE, TRUE);
2549 if (!empty($lock)) {
2550 $user = $this->
getAsset($lock[
'userid']);
2551 trigger_localised_error(
'SYS0101', E_USER_NOTICE, $lock_type, $asset->name, $user->name);
2556 $lockid =
'asset.'.$assetid.
'.'.$lock_type;
2557 $source_lockid = ($source_assetid) ?
'asset.'.$source_assetid.
'.'.$lock_type :
'';
2558 if (TRUE !== ($err_msg = $GLOBALS[
'SQ_SYSTEM']->
acquireLock($lockid, $source_lockid, $expires))) {
2559 trigger_localised_error(
'SYS0100', E_USER_NOTICE, $lock_type, $asset->name, $err_msg);
2566 $GLOBALS[
'SQ_SYSTEM']->doTransaction(($success) ?
'COMMIT' :
'ROLLBACK');
2567 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2570 return ($success) ? (($lock_updated) ? 2 : 1) : 0;
2590 if (empty($lock_type) || !is_string($lock_type)) {
2591 trigger_localised_error(
'SYS0075', E_USER_WARNING, $assetid);
2597 $orig_lock_type = $lock_type;
2599 $current_locks = $this->
getLockInfo($assetid, $lock_type, TRUE, FALSE);
2600 if (empty($current_locks))
return TRUE;
2602 $asset = $this->
getAsset($assetid);
2603 assert_not_null($asset);
2612 foreach ($current_locks as $lock_type => $lock) {
2613 if (empty($lock))
continue;
2615 if ((
int) $lock[
'userid'] != $GLOBALS[
'SQ_SYSTEM']->currentUserid()) {
2616 if ($can_force === NULL) {
2617 $can_force = $asset->canForceablyAcquireLock($orig_lock_type);
2622 $user = $this->
getAsset($lock[
'userid']);
2623 trigger_localised_error(
'SYS0264', E_USER_WARNING, $lock_type, $asset->name, $user->name);
2629 if (TRUE !== ($err_msg = $GLOBALS[
'SQ_SYSTEM']->
releaseLock(
'asset.'.$assetid.
'.'.$lock_type))) {
2630 trigger_localised_error(
'SYS0109', E_USER_NOTICE, $lock_type, $asset->name, $err_msg);
2654 $current_locks = $this->
getLockInfo($assetid, $lock_type, TRUE, TRUE, TRUE, TRUE);
2656 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
2657 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
2661 foreach (array_keys($current_locks) as $lock_type) {
2662 if (!empty($lock_type)) {
2663 if (TRUE !== ($err_msg = $GLOBALS[
'SQ_SYSTEM']->
updateLock(
'asset.'.$assetid.
'.'.$lock_type, $expires))) {
2664 trigger_localised_error(
'SYS0122', E_USER_NOTICE, $assetid, $err_msg);
2672 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
2674 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
2677 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
2696 function getLockInfo($assetid, $lock_type, $force_array=FALSE, $full_chain=FALSE, $check_expires=TRUE, $allow_only_one=FALSE)
2698 $lock_types = $this->
getLockTypes($assetid, $lock_type);
2702 foreach ($lock_types as $each_lock_type) {
2703 $lockids[] =
'asset.'.$assetid.
'.'.$each_lock_type;
2704 $last_lock =
'asset.'.$assetid.
'.'.$each_lock_type;
2708 if (!empty($lockids)) {
2710 $lock = $GLOBALS[
'SQ_SYSTEM']->getLockInfo($lockids, $full_chain, $check_expires, $allow_only_one);
2712 $lock = $GLOBALS[
'SQ_SYSTEM']->getLockInfo($last_lock, $full_chain, $check_expires, $allow_only_one);
2715 $all_locks = Array();
2716 if ($allow_only_one) {
2717 $all_locks[] = $lock;
2722 foreach ($lock_types as $each_lock_type) {
2723 $current_lock_id =
'asset.'.$assetid.
'.'.$each_lock_type;
2724 $locks[$each_lock_type] = Array();
2725 foreach ($all_locks as $each_key => $each_lock) {
2726 if (isset($each_lock[
'lockid']) && ($current_lock_id == $each_lock[
'lockid'])) {
2727 $each_lock[
'lock_type'] = $lock_type;
2728 $each_lock[
'source_assetid'] = preg_replace(
'|^asset\.(.*)\.[\w]+$|',
'\1', $each_lock[
'source_lockid']);
2730 for (reset($each_lock[
'chained_assets']); NULL !== ($k = key($each_lock[
'chained_assets'])); next($each_lock[
'chained_assets'])) {
2731 $each_lock[
'chained_assets'][$k][
'assetid'] = preg_replace(
'/^asset\.([0-9]+(:.+)?)\..*$/',
'\1', $each_lock[
'chained_assets'][$k][
'lockid']);
2732 $each_lock[
'chained_assets'][$k][
'source_assetid'] = preg_replace(
'/^asset\.([0-9]+(:.+)?)\..*$/',
'\1', $each_lock[
'chained_assets'][$k][
'source_lockid']);
2735 $locks[$each_lock_type] = $each_lock;
2742 if (!$force_array && count($locks) == 1) {
2743 return reset($locks);
2765 if (!is_string($lock_type) || empty($lock_type)) {
2769 if (!isset($this->_tmp[
'lock_types'][$assetid])) {
2770 $asset = $this->
getAsset($assetid);
2772 if (is_null($asset))
return Array();
2773 $this->_tmp[
'lock_types'][$assetid] = $asset->lockTypes();
2776 if ($lock_type !==
'all') {
2777 if (!isset($this->_tmp[
'lock_types'][$assetid][$lock_type])) {
2780 $bits = bit_elements($this->_tmp[
'lock_types'][$assetid][$lock_type]);
2781 $lock_types = Array();
2782 foreach ($bits as $bit) {
2783 if (FALSE !== ($k = array_search($bit, $this->_tmp[
'lock_types'][$assetid]))) {
2789 $lock_types = Array();
2790 foreach ($this->_tmp[
'lock_types'][$assetid] as $lock_type => $bit) {
2791 if (preg_match(
'/^0*10*$/', decbin($bit))) {
2792 $lock_types[] = $lock_type;
2825 function getLink($assetid, $link_type=NULL, $type_code=
'', $strict_type_code=TRUE, $value=NULL, $side_of_link=
'major', $exclusive=NULL)
2827 assert_valid_assetid($assetid);
2828 $bind_vars = Array();
2831 $id_parts = explode(
':', $assetid);
2832 if (isset($id_parts[1])) {
2833 $asset = $this->
getAsset($id_parts[0]);
2834 $link = $asset->getLink($assetid, $link_type, $type_code, $strict_type_code, $value, $side_of_link, $exclusive);
2839 assert_false($side_of_link !=
'major' && $side_of_link !=
'minor',
'Unknown Side of Link "'.$side_of_link.
'"');
2841 $other_side = ($side_of_link ==
'major') ?
'minor' :
'major';
2844 $sql =
'SELECT l.linkid, l.'.$other_side.
'id, l.value, l.link_type,
2845 l.type_code as '.$other_side.
'_type_code, l.sort_order, l.is_dependant, l.is_exclusive, l.locked
2846 FROM '.SQ_TABLE_RUNNING_PREFIX.
'vw_ast_lnk_'.$other_side.
' l';
2848 $where =
'l.'.$side_of_link.
'id = :assetid';
2849 $bind_vars[
'assetid'] = $assetid;
2851 if (!is_null($link_type)) {
2853 AND l.link_type = :link_type';
2854 $bind_vars[
'link_type'] = $link_type;
2857 if (!is_null($exclusive)) {
2858 $where .=
' AND l.is_exclusive = :is_exclusive';
2859 $bind_vars[
'is_exclusive'] = ($exclusive) ?
'1' :
'0';
2864 $type_code_cond =
'';
2865 if (is_array($type_code)) {
2866 $type_query_str = Array();
2867 for (reset($type_code); NULL !== ($i = key($type_code)); next($type_code)) {
2868 $type_query_str[$i] =
':type_code_'.$i;
2869 $bind_vars[
'type_code_'.$i] = $type_code[$i];
2871 $type_code_cond =
'IN ('.implode(
', ', $type_query_str).
')';
2873 $type_code_cond =
'= :type_code';
2874 $bind_vars[
'type_code'] = $type_code;
2877 if ($strict_type_code) {
2878 $where .=
' AND l.type_code '.$type_code_cond;
2880 $where .=
' AND l.type_code IN (
2882 FROM sq_ast_typ_inhd
2883 WHERE inhd_type_code '.$type_code_cond.
'
2888 if (!is_null($value)) {
2889 $where .=
' AND (l.value = :link_value';
2890 if ($value ==
'') $where .=
' OR l.value IS NULL';
2893 $bind_vars[
'link_value'] = $value;
2896 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'lnk_',
'WHERE', FALSE);
2897 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'ast_',
'WHERE', FALSE);
2899 $sql .= $where.
' ORDER BY l.sort_order';
2903 foreach ($bind_vars as $bind_var => $bind_value) {
2907 if (!empty($result)) $result = $result[0];
2908 }
catch (Exception $e) {
2909 throw new Exception(
'Unable to get link for asset with assetid: '.$assetid.
' due to database error: '.$e->getMessage());
2930 function getShadowLinkByAsset($assetid, $other_assetid=NULL, $link_types=NULL, $value=NULL, $side_of_link=
'major', $force_array=FALSE)
2932 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
2934 assert_valid_assetid($assetid);
2935 assert_false($side_of_link !=
'major' && $side_of_link !=
'minor',
'Unknown Side of Link "'.$side_of_link.
'"');
2937 if (!is_null($other_assetid)) {
2938 assert_valid_assetid($other_assetid);
2940 if (!$other_assetid || is_object($other_assetid)) {
2941 trigger_localised_error(
'SYS0108', E_USER_WARNING);
2946 $other_side = ($side_of_link ==
'major') ?
'minor' :
'major';
2949 $sql =
'SELECT l.linkid, l.'.$other_side.
'id, l.value, l.link_type
2950 FROM '.SQ_TABLE_RUNNING_PREFIX.
'shdw_ast_lnk l';
2952 $where =
'l.'.$side_of_link.
'id = :assetid';
2954 if (!is_null($other_assetid)) {
2958 if (!is_null($link_types)) {
2959 $where .=
' AND '.db_extras_bitand(
MatrixDAL::getDbType(),
'l.link_type', $link_types).
' > 0 ';
2962 if (!is_null($value)) {
2963 $where .=
' AND l.value = '.MatrixDAL::quote($value);
2966 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'lnk_',
'WHERE', FALSE);
2967 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'ast_',
'WHERE', FALSE);
2973 }
catch (Exception $e) {
2974 throw new Exception(
'Unable to get shadow link for this assetid: '.$assetid.
' due to database error: '.$e->getMessage());
2977 if (!$force_array && count($result) == 1) {
2999 assert_false($side_of_link !=
'major' && $side_of_link !=
'minor',
'Unknown Side of Link "'.$side_of_link.
'"');
3001 $other_side = ($side_of_link ==
'major') ?
'minor' :
'major';
3003 $id_parts = explode(
':', $linkid);
3004 if (isset($id_parts[1])) {
3005 $bridge = $this->
getAsset($id_parts[0]);
3006 $link = $bridge->getLinkById($linkid, $assetid, $side_of_link);
3013 $sql =
'SELECT l.linkid, l.value, l.link_type, l.sort_order, l.is_dependant, l.is_exclusive, l.locked, ';
3014 $where =
'l.linkid = :linkid';
3017 if ($assetid !== 0) {
3018 $sql .=
'l.'.$other_side.
'id, l.type_code as '.$other_side.
'_type_code
3019 FROM '.SQ_TABLE_RUNNING_PREFIX.
'vw_ast_lnk_'.$other_side.
' l';
3020 $where .=
' AND l.'.$side_of_link.
'id = :assetid';
3022 $sql .=
'l.majorid, l.type_code as minor_type_code, l.minorid, a.type_code as major_type_code
3023 FROM '.SQ_TABLE_RUNNING_PREFIX.
'vw_ast_lnk_minor l
3024 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a ON l.majorid = a.assetid';
3026 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
3030 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'lnk_',
'WHERE', FALSE);
3031 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'ast_',
'WHERE', FALSE);
3036 if ($assetid !== 0) {
3040 if (empty($result)) {
3042 }
else if (isset($result[0])) {
3043 $result = $result[0];
3045 }
catch (Exception $e) {
3046 throw new Exception(
'Unable to get link details for asset with assetid: '.$assetid.
' due to database error: '.$e->getMessage());
3077 function getLinkByAsset($assetid, $other_assetid, $link_types=NULL, $value=NULL, $side_of_link=
'major', $force_array=FALSE, $dependant=NULL, $exclusive=NULL)
3079 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
3081 assert_valid_assetid($assetid);
3082 assert_valid_assetid($other_assetid);
3083 assert_false($side_of_link !=
'major' && $side_of_link !=
'minor',
'Unknown Side of Link "'.$side_of_link.
'"');
3085 if (!$other_assetid || is_object($other_assetid)) {
3086 trigger_localised_error(
'SYS0108', E_USER_WARNING);
3090 if (!is_array($other_assetid)) {
3091 $other_assetid = Array($other_assetid);
3095 $other_shadow_assetids = Array();
3096 $shadow_links = Array();
3103 $assetid_shadow_parts = explode(
':', $assetid);
3104 $assetid_is_shadow = (count($assetid_shadow_parts) > 1);
3106 if ($assetid_is_shadow) {
3107 $other_shadow_assetids = $other_assetid;
3108 $other_assetid = Array();
3110 foreach ($other_assetid as $key => $other_assetid_value) {
3111 $shadow_parts = explode(
':', $other_assetid_value);
3113 if (count($shadow_parts) > 1) {
3114 $other_shadow_assetids[] = $other_assetid_value;
3115 unset($other_assetid[$key]);
3121 if (!empty($other_shadow_assetids)) {
3125 if ($side_of_link ==
'major') {
3126 $majorids = Array($assetid);
3127 $minorids = $other_shadow_assetids;
3129 $majorids = $other_shadow_assetids;
3130 $minorids = Array($assetid);
3133 $side_of_link =
'major';
3139 foreach ($majorids as $majorid) {
3140 $major_shadow_parts = FALSE;
3141 $id_parts = explode(
':', $majorid);
3142 if (isset($id_parts[1])) {
3143 $major_shadow_parts = Array(
3144 'bridgeid' => $id_parts[0],
3145 'shadowid' => $id_parts[1],
3149 foreach ($minorids as $minorid) {
3150 $minor_shadow_parts = FALSE;
3151 $id_parts = explode(
':', $minorid);
3152 if (isset($id_parts[1])) {
3153 $minor_shadow_parts = Array(
3154 'bridgeid' => $id_parts[0],
3155 'shadowid' => $id_parts[1],
3159 if (!empty($major_shadow_parts)) {
3162 $asset = $this->
getAsset($major_shadow_parts[
'bridgeid']);
3163 if (!is_null($asset)) {
3165 $link = $asset->getLinkByAsset($majorid, $minorid, $link_types, $value, $side_of_link, TRUE, $dependant, $exclusive);
3168 $shadow_links = array_merge($shadow_links, $link);
3170 if (!empty($minor_shadow_parts)) {
3174 $link = $this->
getShadowLinkByAsset($majorid, $minorid, $link_types, $value, $side_of_link, TRUE, $dependant, $exclusive);
3175 $shadow_links = array_merge($shadow_links, $link);
3187 if (!empty($other_assetid)) {
3189 $bind_vars = Array();
3191 $prepared_otherids = Array();
3192 foreach ($other_assetid as $id) {
3193 $prepared_otherids[] =
'\''.$id.
'\'';
3196 $other_side = ($side_of_link ==
'major') ?
'minor' :
'major';
3198 $sql =
'SELECT l.linkid, l.'.$other_side.
'id, l.value, l.link_type,
3199 l.type_code as '.$other_side.
'_type_code, l.sort_order, l.is_dependant, l.is_exclusive, l.locked
3200 FROM '.SQ_TABLE_RUNNING_PREFIX.
'vw_ast_lnk_'.$other_side.
' l';
3202 $where =
'l.'.$side_of_link.
'id = :assetid
3203 AND l.'.$other_side.
'id IN ('.implode(
',', $prepared_otherids).
')';
3204 $bind_vars[
'assetid'] = $assetid;
3206 if (!is_null($link_types)) {
3207 $where .=
' AND '.db_extras_bitand(
MatrixDAL::getDbType(),
'l.link_type', $link_types).
' > 0 ';
3209 if (!is_null($value)) {
3210 if (empty($value)) {
3211 $where .=
' AND (l.value = :value OR l.value IS NULL)';
3213 $where .=
' AND l.value = :value';
3215 $bind_vars[
'value'] = $value;
3217 if (!is_null($dependant)) {
3218 $where .=
' AND l.is_dependant = :is_dependant';
3219 $bind_vars[
'is_dependant'] = ($dependant) ?
'1' :
'0';
3221 if (!is_null($exclusive)) {
3222 $where .=
' AND l.is_exclusive = :is_exclusive';
3223 $bind_vars[
'is_exclusive'] = ($exclusive) ?
'1' :
'0';
3226 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'lnk_',
'WHERE', FALSE);
3227 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'ast_',
'WHERE', FALSE);
3230 ORDER BY l.sort_order';
3234 foreach ($bind_vars as $bind_var => $bind_value) {
3238 }
catch (Exception $e) {
3239 throw new Exception(
'Unable to get link for assetid: '.$assetid.
' due to database error: '.$e->getMessage());
3247 $result += $shadow_links;
3249 if (!$force_array && count($result) == 1) {
3272 $common_keys = Array();
3273 $merged_array = Array();
3274 if (!is_array($array1)) $array1 = Array();
3275 if (!is_array($array2)) $array2 = Array();
3278 foreach ($array1 as $key => $value) {
3279 if (array_key_exists($key, $array2)) {
3280 $common_keys = array_merge($common_keys, Array($key));
3284 $merged_array[$key] = $array1[$key];
3287 foreach ($array2 as $key => $value) {
3288 if (array_key_exists($key, $array1))
continue;
3291 $merged_array[$key] = $array2[$key];
3294 foreach ($common_keys as $key) {
3295 $merged_array[$key] = array_merge($array1[$key], $array2[$key]);
3297 return $merged_array;
3334 function getLinks($assetid, $link_types, $type_code=
'', $strict_type_code=TRUE, $side_of_link=
'major', $value=NULL, $dependant=NULL, $exclusive=NULL, $sort_by=NULL, $access=NULL, $effective=TRUE)
3336 assert_false($side_of_link !=
'major' && $side_of_link !=
'minor',
'Unknown Side of Link "'.$side_of_link.
'"');
3337 $force_array = FALSE;
3339 if (!is_array($assetid)) {
3340 $assetids = Array($assetid);
3342 $force_array = TRUE;
3343 $assetids = $assetid;
3347 $query_assetids = Array();
3348 foreach ($assetids as $assetid) {
3349 assert_valid_assetid($assetid);
3353 $id_parts = explode(
':', $assetid);
3354 if (isset($id_parts[1])) {
3355 $real_assetid = $id_parts[0];
3356 $asset = $this->
getAsset($real_assetid);
3357 if (is_null($asset))
continue;
3359 $links[$assetid] = $asset->getLinks($assetid, $link_types, $type_code, $strict_type_code, $side_of_link, $sort_by, $dependant, $exclusive);
3364 if (($side_of_link ==
'minor') && !$exclusive && !$dependant) {
3373 a.type_code AS major_type_code
3375 '.SQ_TABLE_RUNNING_PREFIX.
'shdw_ast_lnk l
3376 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a on l.majorid = a.assetid';
3378 $where =
'minorid = '.MatrixDAL::quote($assetid);
3379 if(!is_null($link_types)){
3380 $where .=
' AND '.db_extras_bitand(MatrixDAL::GetDbType(),
'l.link_type',
MatrixDAL::quote($link_types)).
' > 0 ';
3383 if ($strict_type_code) {
3384 $where .=
' AND a.type_code IN (';
3385 if (is_array($type_code)) {
3386 foreach ($type_code as $index => $typ_cd) {
3389 $where .= implode(
', ', $type_code);
3396 foreach ($type_ancestors as $i => $v) {
3399 if (is_array($type_code)) {
3400 foreach ($type_code as $index => $typ_cd) {
3406 $where .=
' AND a.type_code IN ('.implode(
', ', $type_ancestors).
')';
3409 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
3410 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
3416 }
catch (Exception $e) {
3417 throw new Exception(
'Could not get shadow links of asset ID #'.$assetid.
' due to database error: '.$e->getMessage());
3420 $shdw_links = Array();
3421 foreach ($result as $shdw_link) {
3422 $shdw_links[] = Array(
3423 'linkid' => $shdw_link[
'linkid'],
3424 'majorid' => $shdw_link[
'majorid'],
3425 'major_type_code' => $shdw_link[
'major_type_code'],
3426 'minorid' => $shdw_link[
'minorid'],
3427 'value' => $shdw_link[
'value'],
3428 'link_type' => $shdw_link[
'link_type'],
3429 'is_dependant' =>
'0',
3430 'is_exclusive' =>
'0',
3432 'locked' => $shdw_link[
'locked'],
3438 $_links_to_merge = is_null($links[$assetid]) ? Array() : $links[$assetid];
3439 $links[$assetid] = array_merge($_links_to_merge, $shdw_links);
3449 if ($side_of_link ==
'major') {
3450 $asset = $this->
getAsset($assetid);
3451 if (is_null($asset))
return Array();
3452 if (implements_interface($asset,
'bridge')) {
3453 $links[$assetid] = $asset->getLinks($assetid, $link_types, $type_code, $strict_type_code, $side_of_link, $sort_by, $dependant, $exclusive);
3460 $query_assetids[] = $assetid;
3464 if (!empty($query_assetids)) {
3466 if (!is_null($value) && !is_array($value)) {
3468 'link_value' => Array($value),
3473 $links_query = $this->
generateGetLinksQuery($query_assetids, $link_types, $type_code, $strict_type_code, $side_of_link, $value, $dependant, $exclusive, $sort_by, $access, $effective);
3475 if (!empty($links_query)) {
3476 $sql = implode(
' ', $links_query[
'sql_array']);
3479 foreach ($links_query[
'bind_vars'] as $bind_var => $bind_value) {
3488 if (count($links) == 1 && !$force_array) {
3489 $keys = array_keys($links);
3490 $links = $links[$keys[0]];
3514 function getAllChildLinks($assetid, $link_type=0, $access=NULL, $effective=TRUE, $bind_prefix=
'gc_', $depth=0)
3516 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
3518 if (!isset($this->_tmp[
'child_links'][$assetid])) {
3519 $id_parts = explode(
':', $assetid);
3520 if (isset($id_parts[1])) {
3521 $asset = $this->
getAsset($id_parts[0]);
3522 $links = $asset->getAllChildLinks($assetid, $link_type);
3528 $asset = $this->
getAsset($assetid);
3529 $shadow_links = Array();
3530 if (implements_interface($asset,
'bridge')) {
3531 $shadow_links = $asset->getAllChildLinks($assetid, $link_type);
3536 $where =
'l.minorid = :assetid';
3537 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
't');
3538 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
3539 $sql =
'SELECT t.treeid
3540 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree t INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l ON t.linkid = l.linkid'.$where;
3547 }
catch (Exception $e) {
3548 throw new Exception(
'Unable to get treeid for asset: '.$assetid.
' due to database error: '.$e->getMessage());
3551 $current_level = strlen($treeid) / SQ_CONF_ASSET_TREE_SIZE;
3553 $where =
't.treeid LIKE :'.$bind_prefix.
'treeid_like
3554 AND t.treeid > :'.$bind_prefix.
'treeid';
3556 $where .=
' AND ((LENGTH(t.treeid) / '.SQ_CONF_ASSET_TREE_SIZE.
') '.(($current_level) ?
' - '.$current_level :
'').
') <= :gc_max_tree_depth';
3560 if ($link_type != 0) {
3564 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
3565 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
't');
3566 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
3568 $select =
'SELECT SUBSTR(t.treeid, '.MatrixDAL::quote((
int) strlen($treeid) + 1).
') as treeid,
3569 ((LENGTH(t.treeid) / '.SQ_CONF_ASSET_TREE_SIZE.
') '.(($current_level) ?
' - '.$current_level :
'').
') as lvl,
3570 l.linkid, a.assetid, a.short_name, a.type_code, l.link_type, l.sort_order, l.value, l.is_dependant, l.is_exclusive';
3571 $from =
'FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree t
3572 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l ON t.linkid = l.linkid
3573 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a ON l.minorid = a.assetid';
3574 $order_by =
'ORDER BY t.treeid';
3578 $bind_vars[$bind_prefix.
'treeid_like'] = $treeid.
'%';
3579 $bind_vars[$bind_prefix.
'treeid'] = $treeid;
3580 if ($depth != 0) $bind_vars[$bind_prefix.
'max_tree_depth'] = $depth;
3582 if (!is_null($access)) {
3583 $access = (String)$access;
3585 $group_by =
'GROUP BY t.treeid, l.linkid, l.minorid, l.link_type, l.sort_order, l.value, l.is_dependant, l.is_exclusive, a.assetid, a.short_name, a.type_code, a.name';
3586 if (!$GLOBALS[
'SQ_SYSTEM']->userRoot() && !$GLOBALS[
'SQ_SYSTEM']->userSystemAdmin()) {
3587 $from .=
' INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_perm p ON p.assetid = a.assetid ';
3588 $from .=
' LEFT JOIN '.SQ_TABLE_RUNNING_PREFIX.
'vw_ast_role r ON (p.userid = r.roleid AND r.assetid = a.assetid) ';
3590 $current_user = $this->
getAsset($GLOBALS[
'SQ_SYSTEM']->user->id);
3591 $userids = $current_user->getUserGroups();
3593 $userids[] = (String)$GLOBALS[
'SQ_SYSTEM']->user->id;
3595 $userids[] = $public_userid;
3597 $p_userids_str = Array();
3598 $r_userids_str = Array();
3599 for (reset($userids); NULL !== ($i = key($userids)); next($userids)) {
3600 $p_userids_str[$i] =
':'.$bind_prefix.
'p_userids_'.$i;
3601 $r_userids_str[$i] =
':'.$bind_prefix.
'r_userids_'.$i;
3602 $bind_vars[$bind_prefix.
'p_userids_'.$i] = (string)$userids[$i];
3603 $bind_vars[$bind_prefix.
'r_userids_'.$i] = (string)$userids[$i];
3606 $p_userids_str = implode(
',', $p_userids_str);
3607 $r_userids_str = implode(
',', $r_userids_str);
3608 $userid_cond =
' (p.userid IN ('.$p_userids_str.
') OR r.userid IN ('.$r_userids_str.
'))';
3609 $where .=
' AND '.$userid_cond.
'
3611 (p.permission = :'.$bind_prefix.
'_access AND (
3612 p.userid <> :'.$bind_prefix.
'_public_userid
3613 OR r.userid <> :'.$bind_prefix.
'_public_userid_1
3614 OR (p.userid = :'.$bind_prefix.
'_public_userid_2 AND p.granted = \'1\')
3615 OR (r.userid = :'.$bind_prefix.
'_public_userid_3 AND p.granted = \'1\')
3619 $bind_vars[$bind_prefix.
'_access'] = $access;
3620 $bind_vars[$bind_prefix.
'_public_userid'] = $public_userid;
3621 $bind_vars[$bind_prefix.
'_public_userid_1'] = $public_userid;
3622 $bind_vars[$bind_prefix.
'_public_userid_2'] = $public_userid;
3623 $bind_vars[$bind_prefix.
'_public_userid_3'] = $public_userid;
3626 $where .=
' OR (p.permission > :'.$bind_prefix.
'_access_effective AND p.granted = \'1\')';
3627 $bind_vars[$bind_prefix.
'_access_effective'] = $access;
3630 $having =
'HAVING MIN(p.granted) <> \'0\'';
3631 $group_by .=
', p.assetid';
3636 'select' =>
'('.$select,
3639 'group_by' => $group_by,
3640 'having' => $having,
3641 'order_by' =>
')'.$order_by,
3646 foreach ($bind_vars as $bind_var => $bind_value) {
3651 $child_links = Array();
3652 foreach ($links as $id => $info) {
3653 $child_links[$id] = $info[0];
3655 }
catch (Exception $e) {
3656 throw new Exception(
'Unable to get child links for tree id: '.$treeid.
' due to database error: '.$e->getMessage());
3660 for (reset($child_links); NULL !== ($treeid = key($child_links)); next($child_links)) {
3661 if ($child_links[$treeid][
'is_dependant']) {
3662 $parent_treeid = substr($treeid, 0, -SQ_CONF_ASSET_TREE_SIZE);
3663 if ($parent_treeid ==
'') {
3664 $child_links[$treeid][
'dependant_treeid'] =
'';
3666 if (!isset($child_links[$parent_treeid]))
continue;
3667 $child_links[$treeid][
'dependant_treeid'] = $child_links[$parent_treeid][
'dependant_treeid'];
3670 $child_links[$treeid][
'dependant_treeid'] = $treeid;
3674 $this->_tmp[
'child_links'][$assetid] = $child_links + $shadow_links;
3678 return $this->_tmp[
'child_links'][$assetid];
3698 function getLinkLineages($assetid, $result_limit=0, $from_treeid=NULL, $fields=
'name', $only_significant=FALSE)
3700 assert_valid_assetid($assetid);
3702 $link_lineages = Array();
3703 $assetids = Array();
3705 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
3707 if (is_array($fields)) {
3708 $fields_str =
'a.'.implode(
', a.', $fields);
3710 $fields_str =
'a.'.$fields;
3713 $id_parts = explode(
':', $assetid);
3714 if (isset($id_parts[1])) {
3717 $asset_field = is_array($fields) ?
'name' : $fields;
3718 $bridge_info = $this->
getAssetInfo(Array($id_parts[0]),
'', TRUE, $asset_field);
3722 for (reset($link_lineages); NULL !== ($key = key($link_lineages)); next($link_lineages)) {
3723 $link_lineages[$key][
'lineage'][$id_parts[0]] = $bridge_info[$id_parts[0]];
3726 l.majorid, '.$fields_str.
'
3728 '.SQ_TABLE_RUNNING_PREFIX.
'shdw_ast_lnk l
3729 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a ON l.majorid = a.assetid';
3731 $where =
'l.minorid = '.MatrixDAL::quote($assetid);
3732 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
3733 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
3740 throw new Exception(
'Could not get shadow links of minor asset ID '.$assetid.
' due to database error: '.$e->getMessage());
3745 foreach ($result as $assetid => $name) {
3747 for (reset($lineages); NULL !== ($key = key($lineages)); next($lineages)) {
3748 $lineages[$key][
'lineage'][$assetid] = $name;
3750 $link_lineages = array_merge($link_lineages, $lineages);
3751 if ($result_limit != 0 && count($link_lineages) >= $result_limit) {
3756 if ($result_limit != 0 && count($link_lineages) > $result_limit) {
3757 $link_lineages = array_slice($link_lineages, 0, $result_limit);
3761 foreach ($link_lineages as $key => $value) {
3762 foreach ($value[
'lineage'] as $lineage_key => $lineage_value) {
3763 if (is_array($lineage_value)) {
3764 $link_lineages[$key][
'lineage'][$lineage_key] = $lineage_value[0][0];
3769 return $link_lineages;
3774 if ($only_significant) {
3775 $link_types = SQ_SC_LINK_SIGNIFICANT;
3777 $link_types = SQ_SC_LINK_ALL;
3783 $bind_vars = Array();
3785 $sub_sql =
'SELECT l.majorid FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l';
3786 $sub_where =
'l.minorid = :minorid';
3787 $sub_where .=
' and l.link_type < :link_types';
3788 $bind_vars[
'minorid'] = (string)$assetid;
3789 $bind_vars[
'link_types'] = $link_types;
3790 $sub_where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($sub_where,
'l');
3791 $sub_sql .= $sub_where;
3793 $sql =
'SELECT ct.treeid as our_treeid, cl.minorid, pt.treeid as parent_treeid, a.assetid, '.$fields_str.
'
3794 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk cl
3795 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree ct ON cl.linkid = ct.linkid
3796 INNER JOIN ('.$sub_sql.
') x ON cl.minorid = x.majorid,
3797 '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk pl
3798 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree pt ON pl.linkid = pt.linkid
3799 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a ON a.assetid = pl.minorid
3802 $where =
'ct.treeid LIKE pt.treeid || '.
'\''.
'%'.
'\''.
'
3803 AND pt.treeid <= ct.treeid';
3805 if (!is_null($from_treeid)) {
3806 if (is_array($from_treeid)) {
3807 $treeid_bits = Array();
3808 foreach ($from_treeid as $ftids) {
3810 $treeid_bits[] =
'(pt.treeid LIKE '.
'\''.($ftid.
'%').
'\''.
')';
3812 $where .=
' AND ('.implode(
' OR ', $treeid_bits).
')';
3814 $where .=
' AND pt.treeid LIKE :from_treeid';
3815 $bind_vars[
'from_treeid'] = $from_treeid.
'%';
3830 $in_sql = SQ_TABLE_RUNNING_PREFIX.
'get_lineage_treeids(:assetid, :tree_size, :rb_date, :link_types)';
3834 $treeids_query =
"SELECT column_value AS treeid FROM TABLE(" . $in_sql .
")";
3836 $treeids_query =
"SELECT " . SQ_TABLE_RUNNING_PREFIX .
"get_lineage_treeids AS treeid FROM " . $in_sql;
3838 $treeid_bind_vars[
'assetid'] = (string) $assetid;
3839 $treeid_bind_vars[
'tree_size'] = (int) SQ_CONF_ASSET_TREE_SIZE;
3840 $treeid_bind_vars[
'rb_date'] = NULL;
3841 $treeid_bind_vars[
'link_types'] = (int) $link_types;
3845 foreach ($treeid_bind_vars as $bind_var => $bind_value) {
3850 }
catch (Exception $e) {
3858 if (!empty($tree_result)) {
3859 foreach ($tree_result as $row => $info) {
3868 if (!in_array($quoted_treeid, $treeids)) {
3869 $treeids[] = $quoted_treeid;
3874 $in_clauses = Array();
3875 foreach (array_chunk($treeids, 999) as $chunk) {
3876 $in_clauses[] =
' pt.treeid IN ('.implode(
', ', $chunk).
')';
3878 $where .=
' AND ('.implode(
' OR ', $in_clauses).
')';
3882 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'cl');
3883 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'ct');
3884 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'pl');
3885 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'pt');
3886 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
3889 ORDER BY cl.linkid, ct.treeid, pt.treeid';
3893 foreach ($bind_vars as $bind_var => $bind_value) {
3897 }
catch (Exception $e) {
3908 $asset_links = $this->
getLinks($assetid, $link_types,
'', TRUE,
'minor');
3910 $link_info = Array();
3911 foreach ($asset_links as $link_data) {
3912 $link_info[$link_data[
'majorid']][] = $link_data;
3916 foreach (array_values($result) as $link_tree) {
3918 $parent_data = $link_tree[count($link_tree) -1];
3919 $majorid = $parent_data[
'assetid'];
3921 if (!isset($link_info[$majorid]))
continue;
3923 foreach ($link_info[$majorid] as $link_data) {
3924 $link_type = $link_data[
'link_type'];
3925 $linkid = $link_data[
'linkid'];
3926 $link_value = $link_data[
'value'];
3928 $asset_lineage = Array();
3929 foreach ($link_tree as $tree_data) {
3930 if ($tree_data[
'assetid'] == $majorid)
continue;
3931 if (is_array($fields)) {
3932 $asset_lineage[$tree_data[
'assetid']] = Array();
3933 foreach ($fields as $field_name) {
3934 $asset_lineage[$tree_data[
'assetid']][$field_name] = $tree_data[$field_name];
3937 $asset_lineage[$tree_data[
'assetid']] = $tree_data[$fields];
3941 if (is_array($fields)) {
3942 $asset_lineage[$tree_data[
'assetid']] = Array();
3943 foreach ($fields as $field_name) {
3944 $asset_lineage[$parent_data[
'assetid']][$field_name] = $parent_data[$field_name];
3947 $asset_lineage[$parent_data[
'assetid']] = $parent_data[$fields];
3950 $link_lineages[] = Array(
3951 'linkid' => $linkid,
3952 'link_type' => $link_type,
3953 'link_value'=> $link_value,
3954 'lineage' => $asset_lineage,
3958 if ($result_limit != 0 && $result_count == $result_limit) {
3964 return $link_lineages;
3999 function getParents($assetid, $type_code=
'', $strict_type_code=TRUE, $sort_by=NULL, $access=NULL, $effective=TRUE, $min_height=NULL, $max_height=NULL, $ignore_bridge=FALSE, $link_value_wanted=NULL, $bind_var_prefix=
'gp_')
4003 $id_parts = explode(
':', $assetid);
4004 if (isset($id_parts[1])) {
4005 $real_assetid = $id_parts[0];
4006 $asset = $this->
getAsset($real_assetid);
4009 if (!$ignore_bridge) {
4010 $parents = $asset->getParents($assetid, $type_code, $strict_type_code);
4013 $bind_vars = array();
4018 '.SQ_TABLE_RUNNING_PREFIX.
'shdw_ast_lnk sl';
4020 $where =
'sl.minorid = :shadow_assetid AND sl.link_type != :link_notice';
4021 $bind_vars[
'shadow_assetid'] = $assetid;
4022 $bind_vars[
'link_notice'] = SQ_LINK_NOTICE;
4024 if (!empty($type_code)) {
4025 $sql .=
' INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast a
4026 ON sl.majorid = a.assetid ';
4027 $type_codes_quoted = Array();
4028 $all_type_codes = is_array($type_code) ? $type_code : Array($type_code);
4029 foreach ($all_type_codes as $tc) {
4032 if (!$strict_type_code) {
4033 foreach ($all_type_codes as $tc) {
4035 foreach ($ancestors as $ancestor) {
4040 if (count($type_codes_quoted) == 1) {
4041 $where .=
' AND a.type_code = '.reset($type_codes_quoted);
4043 $where .=
' AND a.type_code IN ('.implode(
',', $type_codes_quoted).
')';
4046 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
4049 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'sl');
4052 foreach ($bind_vars as $bind_var => $bind_value) {
4058 }
catch (Exception $e) {
4059 throw new Exception(
'Unable to get parents from due to the following database error:'.$e->getMessage());
4062 $shdw_parents = $this->
getAssetInfo($shdw_parentids, Array(), TRUE,
'type_code');
4064 $real_parents = Array();
4066 foreach ($shdw_parentids as $parentid) {
4067 $real_parents += $this->
getParents($parentid, $type_code, $strict_type_code, $sort_by, $access);
4070 $parents = $parents + $shdw_parents + $real_parents;
4077 if (!is_null($link_value_wanted) && !is_array($link_value_wanted)) {
4078 $link_value_wanted = Array(
4079 'link_value' => Array($link_value_wanted),
4084 $ret_val = $this->
generateGetParentsQuery($assetid, $type_code, $strict_type_code, $sort_by, $access, $effective, $min_height, $max_height, $link_value_wanted);
4085 if (empty($ret_val))
return Array();
4088 foreach ($ret_val[
'bind_vars'] as $bind_var => $bind_value) {
4094 foreach ($result as $assetid => $row) {
4095 $parents[$assetid] = $row[0][
'type_code'];
4146 function getChildren($assetid, $type_code=
'', $strict_type_code=TRUE, $dependant=NULL, $sort_by=NULL, $access=NULL, $effective=TRUE, $min_depth=NULL, $max_depth=NULL, $direct_shadows_only=TRUE, $link_value_wanted=NULL, Array $link_types_wanted=Array(), $expand_shadows=FALSE)
4148 assert_valid_assetid($assetid);
4151 $id_parts = explode(
':', $assetid);
4152 if (isset($id_parts[1])) {
4153 $children = Array();
4154 $real_assetid = $id_parts[0];
4155 $asset = $this->
getAsset($real_assetid);
4156 if (!is_null($asset)) {
4157 if (!method_exists($asset,
'getChildren')) {
4158 trigger_localised_error(
'SYS0204', E_USER_WARNING, $asset->name);
4160 $children = $asset->getChildren($assetid, $type_code, $strict_type_code, $dependant, $sort_by);
4164 trigger_localised_error(
'SYS0206', E_USER_WARNING, $real_assetid);
4170 $asset = $this->
getAsset($assetid);
4171 if (is_null($asset))
return Array();
4172 if (implements_interface($asset,
'bridge')) {
4173 $children = $asset->getChildren($assetid, $type_code, $strict_type_code, $dependant, $sort_by);
4179 if (!is_null($link_value_wanted) && !is_array($link_value_wanted)) {
4180 $link_value_wanted = Array(
4181 'link_value' => Array($link_value_wanted),
4186 $ret_val = $this->
generateGetChildrenQuery($asset, $type_code, $strict_type_code, $dependant, $sort_by, $access, $effective, TRUE, $min_depth, $max_depth, $direct_shadows_only, $link_value_wanted,
'gc_', $link_types_wanted);
4191 if (empty($ret_val))
return Array();
4193 $sql_array = $ret_val[
'sql_array'];
4194 $bind_vars = $ret_val[
'bind_vars'];
4196 foreach ($bind_vars as $bind_var => $bind_value) {
4200 }
catch (Exception $e) {
4201 throw new Exception(
'Unable to get children for asset: '.$assetid.
' due to database error: '.$e->getMessage());
4204 if ($expand_shadows){
4205 foreach (array_keys($result) as $child_id){
4206 $id_parts = explode(
':', $child_id);
4207 if (isset($id_parts[1])) {
4208 $children = $this->
getChildren($child_id, $type_code, $strict_type_code, $dependant, $sort_by);
4209 $result += $children;
4214 if (!is_null($sort_by)) {
4215 $children = Array();
4216 foreach ($result as $assetid => $asset_info) {
4217 $children[$assetid] = $asset_info[0][
'type_code'];
4245 $children = Array();
4247 $asset = $this->
getAsset($assetid);
4248 if (!is_null($asset)) {
4250 $dependant_links = $this->
getLinks($asset->id, SQ_SC_LINK_SIGNIFICANT, $type_code, $strict_type_code,
'major', NULL, 1);
4251 for (reset($dependant_links); NULL !== ($k = key($dependant_links)); next($dependant_links)) {
4252 if (!$dependant_links[$k][
'is_dependant'])
continue;
4253 $children[$dependant_links[$k][
'minorid']] = Array (
4255 'type_code' => $dependant_links[$k][
'minor_type_code'],
4262 $all_links = $this->
getLinks($asset->id, SQ_SC_LINK_SIGNIFICANT,
'', FALSE,
'major', NULL, 1);
4263 for (reset($all_links); NULL !== ($k = key($all_links)); next($all_links)) {
4265 if (!$all_links[$k][
'is_dependant'])
continue;
4266 $children = $children + $this->
getDependantChildren($all_links[$k][
'minorid'],$type_code, $strict_type_code);
4299 $asset = $this->
getAsset($assetid);
4300 if (!is_null($asset)) {
4302 $dependant_links = $this->
getLinks($asset->id, SQ_SC_LINK_SIGNIFICANT, $type_code, $strict_type_code,
'minor', NULL, 1);
4303 if (empty($dependant_links) && !$include_all_dependants) {
4304 $parents[] = $assetid;
4306 for (reset($dependant_links); NULL !== ($k = key($dependant_links)); next($dependant_links)) {
4307 $parentid = $dependant_links[$k][
'majorid'];
4308 if ($include_all_dependants) $parents[] = $parentid;
4309 $parents = array_merge($parents, $this->
getDependantParents($parentid, $type_code, $strict_type_code, $include_all_dependants));
4360 function getAssetTree($majorids, $levels=NULL, $exclude_list=Array(), $link_type=SQ_SC_LINK_FRONTEND_NAV, $include_type_list=Array(), $include_dependants=TRUE)
4362 $tree_data = Array();
4363 if (!is_array($majorids)) $majorids = Array($majorids);
4364 $this->
_getAssetTree($majorids, $tree_data, $levels, $exclude_list, $link_type, $include_type_list, $include_dependants);
4396 function _getAssetTree($majorids, &$tree_data, $levels, $exclude_list, $link_type, $include_type_list, $include_dependants)
4398 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
4403 $assetids = Array();
4406 foreach ($majorids as $id) {
4407 if (empty($tree_data[$id])) {
4410 foreach ($tree_data[$id] as $row) {
4411 $assetids[] = (int) $row[
'assetid'];
4417 $majorids_str = rtrim($majorids_str,
',');
4419 if (empty($majorids_str))
return $assetids;
4421 $exclude_list_before_quote = $exclude_list;
4422 for (reset($exclude_list); NULL !== ($k = key($exclude_list)); next($exclude_list)) {
4426 $exclude_str = implode(
',', $exclude_list);
4428 static $USERIDS_COND = NULL;
4430 if (is_null($USERIDS_COND)) {
4431 if ($GLOBALS[
'SQ_SYSTEM']->userRoot() || $GLOBALS[
'SQ_SYSTEM']->userSystemAdmin()) {
4434 $current_user = $this->
getAsset($GLOBALS[
'SQ_SYSTEM']->user->id);
4435 $userids = $current_user->getUserGroups();
4437 $userids[] = $GLOBALS[
'SQ_SYSTEM']->user->id;
4439 for (reset($userids); NULL !== ($i = key($userids)); next($userids)) {
4442 $USERIDS_COND =
'AND p.userid IN ('.implode(
',', $userids).
')';
4445 if (!empty($USERIDS_COND)) {
4447 GROUP BY a.assetid, l.majorid, a.type_code, a.status, a.name, a.short_name, pt.path, l.sort_order, p.granted
4448 HAVING MIN(p.granted) = \'1\'';
4453 $include_types_str =
'';
4454 if (isset($include_type_list[
'type_code'])) {
4455 $include_types = Array();
4456 $include_inherit = Array();
4458 if (isset($include_type_list[
'inherit'])) {
4459 $include_inherit = $include_type_list[
'inherit'];
4462 foreach ($include_type_list[
'type_code'] as $include_type) {
4463 if (!empty($include_type)) {
4464 if (isset($include_inherit) && !empty($include_inherit) && array_shift($include_inherit)) {
4465 $include_types = array_merge($this->
getTypeDescendants($include_type, TRUE), $include_types);
4467 $include_types[] = $include_type;
4472 if (!empty($include_types)) {
4473 $include_types_str =
'\''.implode(
'\',\
'', $include_types).
'\'';
4478 $sql =
'SELECT DISTINCT a.assetid, l.majorid, a.type_code, a.status, a.name, a.short_name, pt.path, l.sort_order
4479 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast a
4480 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l ON a.assetid = l.minorid
4481 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_path pt ON a.assetid = pt.assetid ';
4482 if (!empty($USERIDS_COND)) {
4484 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'vw_ast_perm p ON a.assetid = p.assetid ';
4487 $majorids_array = explode(
',', $majorids_str);
4488 $in_clause = Array();
4490 foreach (array_chunk($majorids_array, 999) as $chunk) {
4491 $in_clause[] =
' (l.majorid IN ('.implode(
', ', $chunk).
'))';
4495 $where =
' ('.implode(
' OR ',$in_clause).
') AND ('.db_extras_bitand(
MatrixDAL::getDbType(),
'l.link_type', $link_type).
' > 0) ';
4497 if (!empty($exclude_list)) {
4498 $where .=
'AND a.assetid NOT IN ('.$exclude_str.
')';
4501 if (!empty($include_types_str)) {
4502 $where .=
' AND a.type_code IN ('.$include_types_str.
')';
4505 if (!$include_dependants) {
4506 $where .=
' AND l.is_dependant = \'0\'';
4509 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
4510 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
4511 if (!empty($USERIDS_COND)) {
4512 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'p');
4514 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'pt');
4515 $where .=
' '.$USERIDS_COND.
'
4516 ORDER BY l.majorid, l.sort_order';
4520 }
catch (Exception $e) {
4521 throw new Exception(
'Unable to get order of assets as they propogate from passed majorid(s): '.array_contents($majorids).
' due to database error: '.$e->getMessage());
4525 $assetids = Array();
4526 foreach ($result as $row) {
4527 if (!($row[
'status'] & (SQ_STATUS_LIVE | SQ_STATUS_LIVE_APPROVAL))) {
4528 $asset = $this->
getAsset($row[
'assetid']);
4529 $read_access = $asset->readAccess();
4531 $row[
'name'] = $asset->name;
4532 $row[
'short_name'] = $asset->short_name;
4534 if ($row[
'status'] & SQ_SC_STATUS_NOT_LIVE) {
4536 $row[
'name'] =
'(( '.$row[
'name'].
' ))';
4537 $row[
'short_name'] =
'(( '.$row[
'short_name'].
' ))';
4541 if (!$read_access)
continue;
4543 $assetids[] = (int) $row[
'assetid'];
4544 if (!isset($tree_data[$row[
'majorid']])) {
4545 $tree_data[$row[
'majorid']] = Array();
4547 $tree_data[$row[
'majorid']][$row[
'assetid']] = $row;
4551 if (!empty($assetids) && ($levels > 1 || is_null($levels))) {
4553 $this->
_getAssetTree($assetids, $tree_data, $levels, $exclude_list_before_quote, $link_type, $include_type_list, $include_dependants);
4576 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
4577 if (is_array($assetid)) {
4578 $assetids_set = Array();
4579 foreach ($assetid as $this_assetid) {
4580 assert_valid_assetid($this_assetid);
4584 assert_valid_assetid($assetid);
4587 if (empty($link_type)) {
4588 $link_type = SQ_SC_LINK_SIGNIFICANT;
4591 if (is_array($assetid)) {
4592 $sql =
'SELECT l.minorid, t.treeid
4593 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l
4594 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree t ON l.linkid = t.linkid';
4595 $where =
'WHERE l.minorid IN ('.implode(
', ', $assetids_set).
')';
4597 $sql =
'SELECT t.treeid
4598 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l
4599 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree t ON l.linkid = t.linkid';
4600 $where =
'WHERE l.minorid = '.MatrixDAL::quote($assetid);
4605 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
't');
4606 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
4610 if (is_array($assetid)) {
4615 }
catch (Exception $e) {
4616 throw new Exception(
'Unable to get tree ID for asset: '.$e->getMessage());
4636 if (!is_array($linkid)) {
4637 $linkid = Array($linkid);
4642 $bind_vars[
'linkid'] = $linkid;
4644 }
catch (Exception $e) {
4645 throw new Exception(
'Failed to get link tree id: '.$e->getMessage());
4669 if (FALSE !== strpos($assetid,
':')) {
4670 return $this->
assetInTrash(strtok($assetid,
':'), $exclusively);
4676 if ($assetid == $trash->id)
return FALSE;
4681 $sub_sql =
'SELECT (t.treeid || \'%\')
4682 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree t
4683 INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l ON t.linkid = l.linkid ';
4684 $sub_where =
'l.minorid = :trashid';
4685 $sub_where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($sub_where,
't');
4686 $sub_where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($sub_where,
'l');
4687 $sub_sql .= $sub_where;
4690 $sql =
'SELECT COUNT(*)
4691 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk_tree t INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l ON t.linkid = l.linkid';
4692 $where =
'l.minorid = :assetid
4693 AND t.treeid '.(($exclusively) ?
'NOT ' :
'').
'LIKE ('.$sub_sql.
')';
4694 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
't');
4695 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
4702 return ($result == 0);
4704 return ($result > 0);
4731 function countLinks($assetid, $side_of_link=
'major', $link_types=0, $type_code=
'', $strict_type_code=TRUE, $ignore_linkid=0)
4733 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
4735 assert_valid_assetid($assetid);
4736 assert_false($side_of_link !=
'major' && $side_of_link !=
'minor',
'Unknown Side of Link "'.$side_of_link.
'"');
4738 $id_parts = explode(
':', $assetid);
4741 if (isset($id_parts[1])) {
4742 $real_assetid = $id_parts[0];
4743 $asset = $this->
getAsset($real_assetid);
4744 $results = $asset->countLinks($assetid, $side_of_link, $link_types, $type_code, $strict_type_code, $ignore_linkid);
4750 $bind_vars = Array();
4753 $where =
'l.'.$side_of_link.
'id = :assetid';
4754 $bind_vars[
'assetid'] = $assetid;
4759 $extra_table .=
', '.SQ_TABLE_RUNNING_PREFIX.
'ast a';
4760 $where .=
' AND l.minorid = a.assetid ';
4761 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'a');
4763 $type_code_cond =
'';
4764 if (is_array($type_code)) {
4765 for ($i = 0; $i < count($type_code); $i++) {
4768 $type_code_cond =
'IN ('.implode(
', ', $type_code).
')';
4770 $type_code_cond =
'= '.MatrixDAL::quote($type_code);
4773 if ($strict_type_code) {
4774 $where .=
' AND a.type_code '.$type_code_cond;
4776 $where .=
' AND a.type_code IN (
4778 FROM sq_ast_typ_inhd
4779 WHERE inhd_type_code '.$type_code_cond.
'
4784 if ($ignore_linkid) {
4785 $where .=
' AND l.linkid <> :ignore_linkid';
4786 $bind_vars[
'ignore_linkid'] = $ignore_linkid;
4789 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where,
'l');
4790 $sql =
'SELECT COUNT(*)
4791 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk l '.$extra_table.
'
4796 foreach ($bind_vars as $bind_var => $bind_value) {
4801 throw new Exception (
'Unable to count '.$link_type.
' links from asset ID #'.$assetid.
' due to database error: '.$e->getMessage());
4828 function createAssetLink(
Asset $major,
Asset $minor, $link_type, $value=
'', $sort_order=NULL, $dependant=
'0', $exclusive=
'0', $moving=FALSE, $locked=
'0')
4831 if (!$major->id)
return 0;
4832 assert_is_a($minor,
'asset');
4833 if (!is_null($sort_order)) {
4834 $sort_order = (int) $sort_order;
4837 assert_false(!($link_type & SQ_SC_LINK_SIGNIFICANT) && $dependant,
'In order for a link to be dependant it must also be a significant link');
4838 assert_false(!($link_type & SQ_SC_LINK_SIGNIFICANT) && ($locked ==
'1'),
'In order for a link to be locked it must also be a significant link');
4840 $original_link_type = $link_type;
4841 $link_type = (int) $link_type;
4842 if ($link_type != $original_link_type) {
4843 trigger_localised_error(
'SYS0241', E_USER_WARNING);
4848 $majorid_parts = explode(
':', $major->id);
4849 $minorid_parts = explode(
':', $minor->id);
4850 if (isset($minorid_parts[1])) {
4852 if (isset($majorid_parts[1]) || ($majorid_parts[0] == $minorid_parts[0])) {
4854 $bridge = $this->
getAsset($majorid_parts[0]);
4855 $linkid = $bridge->createAssetLink($major, $minor, $link_type, $value, $sort_order, $dependant, $exclusive, $moving);
4866 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
4871 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LINK_INTEGRITY)) {
4873 trigger_localised_error(
'SYS0223', E_USER_WARNING, $major->id);
4874 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4880 $minor->
prepareLink($major,
'minor', $link_type, $value, $sort_order, $dependant, $exclusive);
4881 $major->
prepareLink($minor,
'major', $link_type, $value, $sort_order, $dependant, $exclusive);
4884 $current_link = $this->
getLinkByAsset($major->id, $minor->id, $link_type, $value);
4885 if (empty($current_link) === FALSE) {
4889 if ($trash_folder_id != $major->id) {
4890 trigger_localised_error(
'SYS0192', E_USER_WARNING,
"$major->name (#$major->id)",
"$minor->name (#$minor->id)");
4892 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4893 return $current_link[
'linkid'];
4896 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LINK_INTEGRITY)) {
4900 if (($err_msg = $major->
canCreateLink($minor, $link_type, $exclusive)) !== TRUE) {
4901 trigger_localised_error(
'SYS0301', E_USER_WARNING, $err_msg);
4902 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4908 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
4910 $lock_info = @$this->
getLockInfo($major->id,
'links');
4911 $parent_was_locked = !empty($lock_info);
4913 trigger_localised_error(
'CORE0012', E_USER_WARNING, $major->name);
4914 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4920 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
4921 $db = MatrixDAL::getDB();
4922 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
4924 if ($link_type & SQ_SC_LINK_SIGNIFICANT) {
4930 COUNT(DISTINCT ct.linkid)
4931 FROM sq_ast_lnk_tree pt,
4932 sq_ast_lnk_tree ct INNER JOIN sq_ast_lnk cl ON ct.linkid = cl.linkid
4934 ct.treeid LIKE (pt.treeid || \'%\')
4935 AND ct.treeid >= pt.treeid
4936 AND pt.linkid IN (SELECT linkid
4938 WHERE minorid = :minorid)
4939 AND cl.minorid = :majorid';
4946 }
catch (Exception $e) {
4947 throw new Exception(
'Unable to determine if minor asset "'.$minor->name.
'" (#'.$minor->id.
') in new link is being linked underneath itself, due to database error: '.$e->getMessage());
4950 if ($moving_under) {
4951 trigger_localised_error(
'CORE0114', E_USER_WARNING, $minor->name, $minor->id, $major->name, $major->id);
4952 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4953 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4960 'minorid' => $major->id,
4963 }
catch (Exception $e) {
4964 throw new Exception(
'Unable to determine if major asset "'.$major->name.
'" (#'.$major->id.
') in new link is linked somewhere else, due to database error: '.$e->getMessage());
4967 $existing_treeid = (string) $existing_treeid;
4971 if ((
string) $existing_treeid ==
'-' && get_class($major) !=
'Root_Folder') {
4972 trigger_localised_error(
'SYS0240', E_USER_WARNING, $major->name, $major->id);
4973 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4974 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
4982 COUNT(*) as count, MAX(sort_order) as max
4986 majorid = :majorid';
4994 }
catch (Exception $e) {
4995 throw new Exception(
'Unable to determine sort order range for new link between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
4998 $max = ($row[
'count'] > 0) ? (
int) $row[
'max'] + 1 : 0;
4999 if (is_null($sort_order) || (int) $sort_order > (
int) $max || (int) $sort_order < 0) {
5000 $sort_order = (int) $max;
5010 sort_order = sort_order + 1
5013 AND sort_order >= :sort_order';
5015 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5022 }
catch (Exception $e) {
5023 throw new Exception(
'Unable to shift sort orders of children of "'.$major->name.
'" (#'.$major->id.
') up one, due to database error: '.$e->getMessage());
5026 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5059 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5075 }
catch (Exception $e) {
5076 throw new Exception(
'Unable to add new link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5079 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5081 if ($link_type & SQ_SC_LINK_SIGNIFICANT) {
5083 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
5088 t.treeid, t.num_kids
5091 INNER JOIN sq_ast_lnk l ON t.linkid = l.linkid
5093 l.minorid = :minorid';
5100 if (empty($result)) {
5101 $minor_tree = Array();
5103 $minor_tree = $result[0];
5106 }
catch (Exception $e) {
5107 throw new Exception(
'Unable to get existing child tree information of "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5110 if (empty($minor_tree)) {
5111 $minor_tree = Array(
'treeid' =>
'',
'num_kids' => 0);
5113 $minor_tree[
'treeid'] = (string) $minor_tree[
'treeid'];
5114 $minor_tree[
'num_kids'] = (int) $minor_tree[
'num_kids'];
5118 $requires_update = FALSE;
5126 SUBSTR(ct.treeid, (LENGTH(ct.treeid) + 1) - '.SQ_CONF_ASSET_TREE_SIZE.
') AS treeid
5128 sq_ast_lnk_tree ct';
5130 if ($existing_treeid !=
'-') {
5133 ct.treeid LIKE :existing_treeid_wildcard';
5134 if (!empty($existing_treeid)) {
5135 $sql .=
' AND ct.treeid > :existing_treeid';
5137 $sql .=
' AND LENGTH(ct.treeid) = :length';
5139 $sql .=
' WHERE LENGTH(ct.treeid) = :length';
5141 $sql .=
' AND linkid > 0 ORDER BY treeid DESC';
5146 $bind_vars = Array();
5147 if ($existing_treeid !=
'-') {
5149 $sql = str_replace(
':existing_treeid_wildcard',
MatrixDAL::quote($existing_treeid.
'%'), $sql);
5151 $bind_vars[
'existing_treeid_wildcard'] = $existing_treeid.
'%';
5153 if (!empty($existing_treeid)) {
5154 $bind_vars[
'existing_treeid'] = $existing_treeid;
5156 $bind_vars[
'length'] = strlen($existing_treeid) + SQ_CONF_ASSET_TREE_SIZE;
5158 $bind_vars[
'length'] = SQ_CONF_ASSET_TREE_SIZE;
5161 foreach ($bind_vars as $bind_name => $bind_value) {
5168 }
catch (Exception $e) {
5169 throw new Exception(
'Unable to get tree data due to database error: '.$e->getMessage());
5172 $treeid = ($existing_treeid ==
'-') ?
'' : $existing_treeid;
5176 if (empty($last_treeid)) {
5177 $sql =
'asset_link_treeid_convert(\'0\', \'1\', '.SQ_CONF_ASSET_TREE_BASE.
', '.SQ_CONF_ASSET_TREE_SIZE.
')';
5180 $new_treeid = ($existing_treeid ==
'-') ? $free_treeid : $existing_treeid.$free_treeid;
5195 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5203 }
catch (Exception $e) {
5204 throw new Exception(
'Unable to add new tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5207 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5215 $sql =
'asset_link_treeid_convert(:treeid, :encode, :tree_base, :tree_size)';
5217 'treeid' => $last_treeid,
5219 'tree_base' => SQ_CONF_ASSET_TREE_BASE,
5220 'tree_size' => SQ_CONF_ASSET_TREE_SIZE,
5225 'treeid' => (
string) ($child_num + 1),
5227 'tree_base' => SQ_CONF_ASSET_TREE_BASE,
5228 'tree_size' => SQ_CONF_ASSET_TREE_SIZE,
5253 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5261 }
catch (Exception $e) {
5262 throw new Exception(
'Unable to reserve new tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5265 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5276 (treeid LIKE :treeid_wildcard OR treeid = :treeid)
5277 AND num_kids = 0 ORDER BY treeid DESC';
5282 $bind_vars = Array();
5284 $sql = str_replace(
':treeid_wildcard',
MatrixDAL::quote($treeid.$free_treeid.
':%'), $sql);
5286 $bind_vars[
'treeid_wildcard'] = $treeid.$free_treeid.
':%';
5288 $bind_vars[
'treeid'] = $treeid.$free_treeid;
5290 foreach ($bind_vars as $bind_name => $bind_value) {
5294 }
catch (Exception $e) {
5295 throw new Exception(
'Unable to get tree data due to database error: '.$e->getMessage());
5298 if ($found_treeid == $treeid.$free_treeid.
':'.$linkid) {
5310 treeid = :treeid_found
5319 (treeid LIKE :treeid_wildcard
5320 OR treeid = :treeid)
5323 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5326 $bind_vars = Array();
5328 $sql = str_replace(
':treeid_wildcard',
MatrixDAL::quote($treeid.$free_treeid.
':%'), $sql);
5330 $bind_vars[
'treeid_wildcard'] = $treeid.$free_treeid.
':%';
5332 $bind_vars[
'linkid'] = -$linkid;
5333 $bind_vars[
'treeid'] = $treeid.$free_treeid;
5334 $bind_vars[
'treeid_found'] = $found_treeid;
5336 foreach ($bind_vars as $bind_name => $bind_value) {
5340 }
catch (Exception $e) {
5341 throw new Exception(
'Unable to attempt to win tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5344 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5348 if ($aff_rows != 0) {
5352 $sql =
'SELECT count(1) FROM sq_ast_lnk_tree
5355 treeid LIKE :treeid_wildcard
5360 $bind_vars = Array();
5361 $bind_vars[
'treeid'] = $treeid.$free_treeid;
5363 $sql = str_replace(
':treeid_wildcard',
MatrixDAL::quote($treeid.$free_treeid.
':%'), $sql);
5365 $bind_vars[
'treeid_wildcard'] = $treeid.$free_treeid.
':%';
5368 foreach ($bind_vars as $bind_name => $bind_value) {
5373 $requires_update = TRUE;
5386 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5392 }
catch (Exception $e) {
5393 throw new Exception(
'Unable to attempt to drop lost tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5396 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5404 trigger_localised_error(
'SYS0310', E_USER_ERROR);
5407 if ($requires_update) {
5415 treeid = :old_treeid';
5417 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5427 }
catch (Exception $e) {
5428 throw new Exception(
'Unable to attempt to update won tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5431 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5436 if ((
string) $existing_treeid ==
'-') {
5441 num_kids = :num_kids
5445 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5453 }
catch (Exception $e) {
5454 throw new Exception(
'Unable to update top-level tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5457 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5464 num_kids = :num_kids
5468 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5476 }
catch (Exception $e) {
5477 throw new Exception(
'Unable to update tree entry for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5480 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5492 (t.treeid || :free_treeid),
5497 INNER JOIN sq_ast_lnk l ON t.linkid = l.linkid
5499 l.minorid = :minorid
5500 AND treeid || :free_treeid_1 <> :treeid';
5502 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5513 }
catch (Exception $e) {
5514 throw new Exception(
'Unable to insert child tree entries for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5517 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5524 num_kids = num_kids + 1
5530 LENGTH(SUBSTR(t.treeid, 1, (LENGTH(t.treeid) - :tree_size))) != 0
5532 SUBSTR(t.treeid, 1, (LENGTH(t.treeid) - :tree_size_1))
5542 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5551 }
catch (Exception $e) {
5552 throw new Exception(
'Unable to insert child tree entries for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5555 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5558 if ($minor_tree[
'treeid'] !=
'') {
5559 $case =
"CASE pt.treeid
5572 ('.$case.
') || :treeid || SUBSTR(ct.treeid, :minor_treeid),
5577 INNER JOIN sq_ast_lnk pl ON pt.linkid = pl.linkid,
5580 pl.minorid = :minorid
5581 AND ct.treeid LIKE :minor_treeid_wildcard
5582 AND ct.treeid > :minor_treeid_1';
5584 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5594 }
catch (Exception $e) {
5595 throw new Exception(
'Unable to insert child tree entries for link #'.$linkid.
', between "'.$major->name.
'" (#'.$major->id.
') and "'.$minor->name.
'" (#'.$minor->id.
'), due to database error: '.$e->getMessage());
5598 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5604 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
5610 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
5612 if (!$parent_was_locked) {
5618 $ms = $GLOBALS[
'SQ_SYSTEM']->getMessagingService();
5620 'major_name' => $major->name,
5621 'minor_name' => $minor->name,
5623 $message = $ms->newMessage(Array(),
'asset.linking.create', $msg_reps);
5624 $message->parameters[
'majorid'] = $major->id;
5625 $message->parameters[
'minorid'] = $minor->id;
5626 $message->parameters[
'linkid'] = $linkid;
5630 $em = $GLOBALS[
'SQ_SYSTEM']->getEventManager();
5631 $em->broadcastEvent($major,
'CreateLink', Array(
'linkid' => $linkid));
5634 if ($major->
type() !=
'trash_folder' && $minor->
type() !=
'trash_folder') {
5637 $link_info[
'majorid'] = $major->id;
5638 $link_info[
'minorid'] = $minor->id;
5639 $link_info[
'linkid'] = $linkid;
5640 $link_info[
'value'] = $value;
5641 $link_info[
'link_type'] = $link_type;
5642 $link_info[
'minor_type_code'] = $minor->
type();
5643 $link_info[
'major_type_code'] = $major->
type();
5644 $link_info[
'sort_order'] = $sort_order;
5645 $link_info[
'is_dependant'] = $dependant;
5646 $link_info[
'is_exclusive'] = $exclusive;
5647 $link_info[
'locked'] = $locked;
5649 $event_data = Array(
'link_info' => $link_info,
'linkid' => $linkid);
5651 if ($major->
type() !=
'root_folder') {
5652 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_link_created', $major, $event_data);
5654 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_link_created', $minor, $event_data);
5657 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
5680 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
5682 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
5683 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
5724 }
catch (Exception $e) {
5725 throw new Exception(
'cannot create Shadow Asset Links due to database error: '.$e->getMessage());
5729 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
5730 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
5751 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
5752 if (!$major->id)
return FALSE;
5754 if (!($minor instanceof
Asset)) {
5755 return translate(
'minor_is_not_asset');
5759 if (($err_msg = $this->
canLinkToType($major, $minor->
type(), $link_type, 0, $exclusive)) !== TRUE) {
5764 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_PERMISSIONS)) {
5765 if ($link_type == SQ_LINK_NOTICE) {
5768 if (($major->status == SQ_STATUS_ARCHIVED) || (!$major->
writeAccess(
''))) {
5769 return translate(
'cannot_create_notice_link_permission_denied', $major->name, $major->id, $minor->name, $minor->id);
5776 if (!($majwa || $minwa)) {
5777 return translate(
'cannot_create_sig_link_no_perm_either', $major->name, $major->id, $minor->name, $minor->id);
5778 }
else if (!$majwa) {
5779 return translate(
'cannot_create_sig_link_no_perm_major', $major->name, $major->id, $minor->name, $minor->id);
5780 }
else if (!$minwa) {
5781 return translate(
'cannot_create_sig_link_no_perm_minor', $major->name, $major->id, $minor->name, $minor->id);
5786 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
5790 if ($link_type & SQ_SC_LINK_WEB_PATHS) {
5792 $bad_paths = $this->
webPathsInUse($major, $paths, $minor->id);
5793 if (!empty($bad_paths)) {
5794 return translate(
'cannot_create_link_paths_in_use', $major->name, $major->id, $minor->name, $minor->id,
'"'.implode(
'", "', $bad_paths).
'"');
5801 if ($link_type & SQ_SC_LINK_SIGNIFICANT) {
5803 $sql =
'SELECT majorid
5804 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_lnk ';
5805 $where =
'minorid = :minor_id
5808 $where .=
' AND is_exclusive = :is_exclusive';
5810 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where);
5820 }
catch (Exception $e) {
5821 throw new Exception(
'Unable to check that minor asset doesnt already have an exclusive link due to database error: '.$e->getMessage());
5824 if ($current_majorid) {
5825 $current_major = $this->
getAsset($current_majorid);
5826 return translate(
'cannot_create_link_exclusive_link', $minor->name, $minor->id, $major->name, $major->id, $current_major->name, $current_majorid);
5831 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
5855 if (!($major instanceof
Asset)) {
5856 return translate(
'major_is_not_asset');
5859 if (!is_string($type_code)) {
5860 return translate(
'type_code_is_not_string');
5863 if (!is_numeric($link_type)) {
5864 return translate(
'link_type_is_not_integer');
5869 array_unshift($types, $type_code);
5879 for ($i = 0; $i < count($types); $i++) {
5881 if (!empty($allowed_links[$link_type][$type]))
break;
5884 if (empty($allowed_links[$link_type][$type])) {
5885 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
5886 return translate(
'asset_type_cannot_be_linktype_linked_to_type', $type_code, link_type_name($link_type), $major->
type());
5889 if (!($link_type & SQ_SC_LINK_SIGNIFICANT) && $exclusive) {
5890 return translate(
'exclusive_links_must_be_significant');
5893 if (!$exclusive && !empty($allowed_links[$link_type][$type][
'exclusive'])) {
5894 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
5895 return translate(
'asset_type_must_be_linktype_exclusively_linked_to_type', $type_code, link_type_name($link_type), $major->
type());
5901 if ($allowed_links[$link_type][$type][
'card'] !=
'M' && $major->id) {
5902 $num_curr_links = $this->
countLinks($major->id,
'major', $link_type, $type, TRUE, $ignore_linkid);
5904 if ($num_curr_links >= (
int) $allowed_links[$link_type][$type][
'card']) {
5905 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
5906 return translate(
'asset_type_can_have_only_linktypes_links_to_type', $this->
getTypeInfo($major->
type(),
'name'), ((
int) $allowed_links[$link_type][$type][
'card']), link_type_name($link_type), $type);
5928 function moveLink($linkid, $to_parentid, $link_type, $to_parent_pos, $link_value=
'')
5931 if (!is_numeric($to_parent_pos)) {
5932 trigger_localised_error(
'SYS0227', E_USER_WARNING);
5937 if (!assert_valid_assetid($to_parentid,
'', FALSE, FALSE)) {
5938 trigger_localised_error(
'SYS0225', E_USER_WARNING);
5943 if (!is_numeric($link_type)) {
5944 trigger_localised_error(
'SYS0221', E_USER_WARNING);
5952 trigger_localised_error(
'SYS0138', E_USER_WARNING, $linkid);
5956 if (isset($link[
'locked']) && $link[
'locked'] ==
'1') {
5957 trigger_localised_error(
'SYS0333', E_USER_WARNING, $linkid);
5961 $old_parent = $this->
getAsset($link[
'majorid'], $link[
'major_type_code']);
5962 if (is_null($old_parent)) {
5963 trigger_localised_error(
'SYS0226', E_USER_WARNING, $link[
'majorid']);
5968 if (!$old_parent->writeAccess(
'')) {
5969 trigger_localised_error(
'SYS0229', E_USER_WARNING, $old_parent->name);
5975 $new_parent = $this->
getAsset($to_parentid,
'', TRUE);
5976 if (is_null($new_parent)) {
5977 trigger_localised_error(
'SYS0224', E_USER_WARNING, $to_parentid);
5983 if (!$new_parent->writeAccess(
'')) {
5984 trigger_localised_error(
'SYS0228', E_USER_WARNING, $new_parent->name);
5991 $minor = $this->
getAsset($link[
'minorid'], $link[
'minor_type_code']);
5993 trigger_localised_error(
'SYS0222', E_USER_WARNING, $link[
'minorid']);
6000 if (TRUE !== ($error_msg = $new_parent->canMoveLink($minor, $old_parent, $link_type))) {
6001 trigger_error($error_msg, E_USER_WARNING);
6008 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
6009 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6013 $new_linkid = $new_parent->createLink($minor, $link_type, $link_value, $to_parent_pos,
'0',
'0', TRUE);
6014 if (!$new_linkid) $success = FALSE;
6018 $success = $old_parent->deleteLink($linkid);
6022 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6024 if ($new_linkid != 0) $link = $GLOBALS[
'SQ_SYSTEM']->am->getLinkById($new_linkid);
6025 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
6031 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6054 return $this->
updateLink($linkid, NULL, NULL, $sort_order);
6074 function updateLink($linkid, $link_type=NULL, $value=NULL, $sort_order=NULL, $locked=NULL)
6079 trigger_localised_error(
'SYS0139', E_USER_WARNING, $linkid);
6083 $id_parts = explode(
':', $linkid);
6084 $minorid_parts = explode(
':', $link[
'minorid']);
6086 if (isset($id_parts[1])) {
6088 $bridge = $this->
getAsset($id_parts[0]);
6089 $result = $bridge->updateLink($linkid, $link_type, $value, $sort_order);
6097 $set_clauses = Array();
6100 if ($link_type == SQ_LINK_TYPE_3 || $link_type == SQ_LINK_NOTICE) {
6101 if (!is_null($locked)) $locked =
'0';
6104 $link_type_changed = (!is_null($link_type) && $link[
'link_type'] != $link_type );
6105 $value_changed = (!is_null($value) && $link[
'value'] != $value );
6106 $sort_order_changed = (!is_null($sort_order) && $link[
'sort_order'] != $sort_order );
6107 $link_locked_changed = (!is_null($locked) && $link[
'locked'] != $locked );
6110 $link_type = (int) $link_type;
6111 $sort_order = (int) $sort_order;
6112 $locked = ($locked ==
'1') ?
'1' :
'0';
6114 $major = $this->
getAsset((
int) $link[
'majorid'], $link[
'major_type_code']);
6115 $minor = $this->
getAsset((
int) $link[
'minorid'], $link[
'minor_type_code']);
6117 $ms = $GLOBALS[
'SQ_SYSTEM']->getMessagingService();
6120 if ($link_type_changed) {
6126 $current_is_sig = (bool) ((
int) $link[
'link_type'] & SQ_SC_LINK_SIGNIFICANT);
6127 $new_is_sig = (bool) ($link_type & SQ_SC_LINK_SIGNIFICANT);
6128 if ($current_is_sig !== $new_is_sig) {
6129 trigger_localised_error(
'SYS0256', E_USER_WARNING, $linkid);
6134 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LINK_INTEGRITY)) {
6135 if (($err_msg = $this->
canLinkToType($major, $minor->type(), $link_type)) !== TRUE) {
6136 trigger_localised_error(
'SYS0255', E_USER_WARNING, $linkid, $err_msg);
6144 if (!($link[
'link_type'] & SQ_SC_LINK_WEB_PATHS) && ($link_type & SQ_SC_LINK_WEB_PATHS)) {
6145 $paths = $minor->getWebPaths();
6146 $bad_paths = $this->
webPathsInUse($major, $paths, $minor->id);
6147 if (!empty($bad_paths)) {
6148 trigger_localised_error(
'SYS0121', E_USER_WARNING, $linkid, implode(
'", "', $bad_paths), $major->name);
6156 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
6158 'linkid' => $linkid,
6159 'major_name' => $major->name,
6160 'minor_name' => $minor->name,
6161 'old_link_type' => link_type_name($link[
'link_type']),
6162 'new_link_type' => link_type_name($link_type),
6164 $message = $ms->newMessage(Array(),
'asset.linking.type', $msg_reps);
6165 $message->parameters[
'majorid'] = $major->id;
6166 $message->parameters[
'minorid'] = $minor->id;
6167 $message->parameters[
'linkid'] = $linkid;
6168 $ms->logMessage($message);
6172 if ($value_changed) {
6177 'linkid' => $linkid,
6178 'major_name' => $major->name,
6179 'minor_name' => $minor->name,
6180 'old_link_value' => $link[
'value'],
6181 'new_link_value' => $value,
6183 $message = $ms->newMessage(Array(),
'asset.linking.value', $msg_reps);
6184 $message->parameters[
'majorid'] = $major->id;
6185 $message->parameters[
'minorid'] = $minor->id;
6186 $message->parameters[
'linkid'] = $linkid;
6187 $ms->logMessage($message);
6191 if ($link_locked_changed) {
6196 'linkid' => $linkid,
6197 'major_name' => $major->name,
6198 'minor_name' => $minor->name,
6199 'link_locked_value' => (($locked ==
'1') ? translate(
'locked') : translate(
'unlocked')),
6201 $message = $ms->newMessage(Array(),
'asset.linking.locked', $msg_reps);
6202 $message->parameters[
'majorid'] = $major->id;
6203 $message->parameters[
'minorid'] = $minor->id;
6204 $message->parameters[
'linkid'] = $linkid;
6205 $ms->logMessage($message);
6209 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
6212 if (isset($minorid_parts[1])) {
6214 if (empty($set_clauses)) {
6219 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
6220 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6225 $set_array = Array();
6227 foreach ($set_clauses as $key => $value) {
6228 $set_array[] = $key.
'='.$value;
6231 $set_string = implode(
',', $set_array);
6236 updated_userid = :updated_userid,
6240 AND majorid = :majorid';
6248 }
catch (Exception $e) {
6249 throw new Exception(
'Unable to update the link due to database error: '.$e->getMessage());
6256 if ($sort_order_changed) {
6260 $sql =
'SELECT COUNT(*) AS count, MAX(sort_order) AS max
6264 majorid = :majorid';
6271 }
catch (Exception $e) {
6272 throw new Exception(
'Unable to get execute the query: '.$e->getMessage());
6275 $max = ($row[
'count'] > 0) ? (
int) $row[
'max'] : 0;
6276 if ($sort_order > $max || $sort_order < 0) {
6283 'linkid' => $linkid,
6284 'major_name' => $major->name,
6285 'minor_name' => $minor->name,
6286 'old_sort_order' => $link[
'sort_order'],
6287 'new_sort_order' => $sort_order,
6289 $message = $ms->newMessage(Array(),
'asset.linking.order', $msg_reps);
6290 $message->parameters[
'majorid'] = $major->id;
6291 $message->parameters[
'minorid'] = $minor->id;
6292 $message->parameters[
'linkid'] = $linkid;
6293 $ms->logMessage($message);
6296 if (empty($set_clauses)) {
6300 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
6301 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6306 $set_array = Array();
6308 foreach ($set_clauses as $key => $value) {
6309 $set_array[] = $key.
'='.$value;
6312 $set_string = implode(
',', $set_array);
6317 updated_userid = :updated_userid,
6321 AND majorid = :majorid';
6328 }
catch (Exception $e) {
6329 throw new Exception(
'Unable to update the link due to database error: '.$e->getMessage());
6332 if ($sort_order_changed) {
6334 if ($link[
'sort_order'] > $sort_order) {
6339 sort_order = sort_order + 1
6342 AND linkid <> :linkid
6343 AND sort_order >= :sort_order_1
6344 AND sort_order <= :sort_order_2';
6353 }
catch (Exception $e) {
6354 throw new Exception(
'Unable to update the link due to database error: '.$e->getMessage());
6362 sort_order = sort_order - 1
6365 AND linkid <> :linkid
6366 AND sort_order >= :sort_order_1
6367 AND sort_order <= :sort_order_2';
6376 }
catch (Exception $e) {
6377 throw new Exception(
'Unable to update the link due to database error: '.$e->getMessage());
6385 if ($link_type_changed) {
6388 if (($link_type & SQ_SC_LINK_WEB_PATHS) || ((int) $link[
'link_type'] & SQ_SC_LINK_WEB_PATHS)) {
6389 if (!$minor->updateLookups()) {
6390 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
6391 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6401 $major->linksUpdated();
6402 $minor->linksUpdated();
6405 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6406 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6423 if ($linkid == 0)
return FALSE;
6425 $id_parts = explode(
':', $linkid);
6426 if (isset($id_parts[1])) {
6427 $bridge = $this->
getAsset($id_parts[0]);
6428 $result = $bridge->deleteAssetLink($linkid);
6434 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
6439 trigger_localised_error(
'SYS0137', E_USER_WARNING, $linkid);
6467 $linkid = $link[
'linkid'];
6470 if ($check_locked && $link[
'locked'] ==
'1') {
6471 trigger_localised_error(
'SYS0334', E_USER_WARNING, $linkid);
6475 $major = $this->
getAsset($link[
'majorid'], $link[
'major_type_code']);
6476 $minor = $this->
getAsset($link[
'minorid'], $link[
'minor_type_code']);
6477 if (is_null($major) || is_null($minor)) {
6481 $asset_was_locked = FALSE;
6482 $parent_was_locked = FALSE;
6486 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
6488 $lock_info = @$this->
getLockInfo($major->id,
'links');
6489 $parent_was_locked = !empty($lock_info);
6491 trigger_localised_error(
'SYS0126', E_USER_WARNING,
'major', $major->name);
6495 $minor_lock_info = @$this->
getLockInfo($minor->id,
'links');
6496 $asset_was_locked = !empty($minor_lock_info);
6498 trigger_localised_error(
'SYS0126', E_USER_WARNING,
'minor', $minor->name);
6504 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LINK_INTEGRITY)) {
6505 if ($link[
'link_type'] == SQ_LINK_NOTICE) {
6507 if (!($major->writeAccess() && $major->accessEffective()) && empty($GLOBALS[
'SQ_PURGING_TRASH'])) {
6508 trigger_localised_error(
'SYS0319', E_USER_WARNING, $linkid, $major->id, $major->name);
6514 if (($err_msg = $minor->canDeleteLink($linkid)) !== TRUE) {
6515 trigger_localised_error(
'SYS0318', E_USER_WARNING, $linkid, $minor->id, $minor->name, $err_msg);
6518 if (($err_msg = $major->canDeleteLink($linkid)) !== TRUE) {
6519 trigger_localised_error(
'SYS0302', E_USER_WARNING, $linkid, $major->id, $major->name, $err_msg);
6525 $minorid_parts = explode(
':', $link[
'minorid']);
6526 if (isset($minorid_parts[1])) {
6528 if (implements_interface($major,
'bridge')) {
6530 $result = $major->deleteAssetLink($linkid);
6532 if ($result != FALSE)
return $result;
6539 require_once SQ_FUDGE_PATH.
'/db_extras/db_extras.inc';
6540 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db3');
6543 if ($link[
'link_type'] & SQ_SC_LINK_SIGNIFICANT) {
6546 $num_other_links = $this->
countLinks($minor->id,
'minor', SQ_SC_LINK_SIGNIFICANT,
'', TRUE, $linkid);
6548 if (!$GLOBALS[
'SQ_PURGING_TRASH'] && ($num_other_links <= 1)) {
6549 $linked_outside_trash = FALSE;
6550 if ($num_other_links == 1) {
6552 $trash_links = $this->
getLinks($minor->id, SQ_SC_LINK_SIGNIFICANT,
'trash_folder', TRUE,
'minor');
6553 if (empty($trash_links)) {
6555 $linked_outside_trash = TRUE;
6558 if (!$linked_outside_trash) {
6560 if (!$GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_before_asset_deleted', $minor, Array())) {
6561 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6562 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6572 if (!$num_other_links && !$GLOBALS[
'SQ_PURGING_TRASH']) {
6574 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LINK_INTEGRITY)) {
6578 if (!$minor->canDelete()) {
6579 trigger_localised_error(
'SYS0069', E_USER_WARNING, $minor->name);
6580 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6581 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6586 if (is_null($trash_folder)) {
6587 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6588 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6594 $perms = Array(SQ_PERMISSION_ADMIN, SQ_PERMISSION_WRITE, SQ_PERMISSION_READ);
6595 foreach ($perms as $perm) {
6596 $all_permissions = $this->
getPermission($minor->id, $perm, NULL, FALSE, FALSE, TRUE);
6597 foreach ($all_permissions as $userid => $granted) {
6601 @$this->
setPermission($minor->id, $userid, $perm, $granted);
6605 if (!$trash_folder->createLink($minor, SQ_LINK_TYPE_2)) {
6606 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6607 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6620 num_kids = num_kids - 1
6626 LENGTH(SUBSTR(t.treeid, 1, LENGTH(t.treeid) - '.SQ_CONF_ASSET_TREE_SIZE.
')) != 0
6628 SUBSTR(t.treeid, 1, LENGTH(t.treeid) - '.SQ_CONF_ASSET_TREE_SIZE.
')
6638 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6643 }
catch (Exception $e) {
6644 throw new Exception(
'Unable to update the link tree for linkid: '.$linkid.
' due to database error: '.$e->getMessage());
6646 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6659 sq_ast_lnk_tree pt, sq_ast_lnk_tree ct
6662 AND (ct.treeid LIKE pt.treeid || '.
'\''.
'%'.
'\''.
'
6663 OR ct.treeid = pt.treeid)
6666 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6671 }
catch (Exception $e) {
6672 throw new Exception(
'Unable to delete tree links for linkid: '.$linkid.
' due to database error: '.$e->getMessage());
6674 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6682 sort_order = sort_order - 1
6685 AND sort_order > :sort_order';
6687 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6693 }
catch (Exception $e) {
6694 throw new Exception(
'Unable to update sort orders for majorid: '.$major->id.
' due to database error: '.$e->getMessage());
6696 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6699 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6701 $bind_vars = Array (
6702 'linkid' => $linkid,
6703 'majorid' => $major->id,
6706 }
catch (Exception $e) {
6707 throw new Exception(
'Unable to delete link with linkid: '.$linkid.
' due to database error: '.$e->getMessage());
6709 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6712 $major->linksUpdated();
6713 $minor->linksUpdated();
6716 if ($GLOBALS[
'SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_LOCKING)) {
6717 if (!$parent_was_locked) {
6720 if (!$asset_was_locked) {
6726 $ms = $GLOBALS[
'SQ_SYSTEM']->getMessagingService();
6728 'major_name' => $major->name,
6729 'minor_name' => $minor->name,
6731 $message = $ms->newMessage(Array(),
'asset.linking.delete', $msg_reps);
6732 $message->parameters[
'majorid'] = $major->id;
6733 $message->parameters[
'minorid'] = $minor->id;
6734 $message->parameters[
'linkid'] = $linkid;
6738 $em = $GLOBALS[
'SQ_SYSTEM']->getEventManager();
6739 $em->broadcastEvent($major,
'DeleteLink', Array(
'linkid' => $linkid));
6742 if ($major->type() !=
'trash_folder' && $minor->type() !=
'trash_folder') {
6743 $event_data = Array(
'link_info' => $link,
'linkid' => $linkid);
6745 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_link_deleted', $minor, $event_data);
6748 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_link_deleted', $major, $event_data);
6753 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6770 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
6771 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6775 $bind_vars = Array(
'linkid' => $linkid);
6777 }
catch (Exception $e) {
6778 throw new Exception(
'Unable to delete shadow asset link with linkid: '.$linkid.
' due to database error: '.$e->getMessage());
6781 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
6782 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
6801 if (!$assetid)
return FALSE;
6804 $parent_links = $this->
getLinks($assetid, SQ_SC_LINK_ALL,
'', TRUE,
'minor');
6805 foreach ($parent_links as $id => $link_details) {
6806 $asset = $this->
getAsset($link_details[
'majorid']);
6807 $msg = $asset->canDeleteLink($link_details[
'linkid']);
6808 if (($check_locked && $link_details[
'locked'] ==
'1') || TRUE !== $msg) {
6809 $msgs[$link_details[
'linkid']] = $msg;
6812 return empty($msgs) ? TRUE : $msgs;
6835 $trash_errors = Array();
6838 if (strpos($assetid,
':') !== FALSE) {
6839 return $trash_errors;
6842 $asset = $this->
getAsset($assetid);
6850 if (!$ignore_other_links) {
6852 $trash_link = $this->
getLinkByAsset($trash_assetid, $asset->id, SQ_LINK_TYPE_1 | SQ_LINK_TYPE_2);
6853 $num_other_links = $this->
countLinks($asset->id,
'minor', SQ_LINK_TYPE_1 + SQ_LINK_TYPE_2,
'', TRUE, $ignore_linkid);
6855 if (!empty($trash_link)) $num_other_links--;
6857 $num_other_links = 0;
6860 if (!$num_other_links) {
6867 $affected_links = $this->
getLinks($asset->id, SQ_LINK_TYPE_3 | SQ_LINK_NOTICE,
'', TRUE,
'minor');
6868 $safe_trash_cron_job = $this->
getLinks($asset->id, SQ_LINK_TYPE_3 | SQ_LINK_NOTICE,
'cron_job_attempt_safe_trash', TRUE,
'minor');
6873 if (!empty($safe_trash_cron_job)) {
6874 foreach (array_keys($affected_links) as $affected_link_key) {
6875 if ($affected_links[$affected_link_key][
'linkid'] == $safe_trash_cron_job[0][
'linkid']) {
6876 unset($affected_links[$affected_link_key]);
6882 if (!empty($affected_links)) {
6884 $trash_errors[
'links'] = $affected_links;
6889 if ($asset->status >= SQ_STATUS_LIVE) {
6890 $trash_errors[
'status'] = $asset->status;
6894 $children = $this->
getChildren($assetid,
'', TRUE, FALSE);
6896 if (!empty($children)) {
6898 $children_ids = array_keys($children);
6900 'link_type' => Array(SQ_LINK_TYPE_3, SQ_LINK_NOTICE),
6901 'status' => SQ_STATUS_LIVE,
6902 'assetid' => $children_ids,
6905 }
catch (Exception $e) {
6906 throw new Exception(
'Unable to check safe trash condition: '.$e->getMessage());
6909 if (!empty($result)) {
6910 $used_minorids = Array();
6913 foreach (array_keys($result) as $result_key) {
6914 $minorid = $result[$result_key][
'minorid'];
6915 if (in_array($minorid, $used_minorids)) {
6916 unset($result[$result_key]);
6918 $used_minorids[] = $minorid;
6922 $trash_errors[
'children'] = $result;
6926 return $trash_errors;
6951 $parent_links = $this->
getLinks($assetid, SQ_SC_LINK_ALL,
'', TRUE,
'minor');
6954 foreach ($parent_links as $index => $link_details) {
6955 $asset = $this->
getAsset($link_details[
'majorid']);
6957 if ($this->
acquireLock($link_details[
'majorid'],
'links')) {
6958 $locked[] = $link_details[
'majorid'];
6960 trigger_localised_error(
'SYS0119', E_USER_WARNING, $assetid, $link_details[
'majorid']);
6962 unset($parent_links[$index]);
6965 foreach ($locked as $aid) {
6971 if (TRUE !== ($msg = $asset->canDeleteLink($link_details[
'linkid']))) {
6972 trigger_localised_error(
'SYS0120', E_USER_WARNING, $assetid, $link_details[
'majorid'], $msg);
6974 unset($parent_links[$index]);
6977 foreach ($locked as $aid) {
6985 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
6986 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
6989 $GLOBALS[
'SQ_SYSTEM']->setRunLevel($GLOBALS[
'SQ_SYSTEM']->getRunLevel() | SQ_SECURITY_LINK_INTEGRITY);
6990 foreach ($parent_links as $link_details) {
6992 if ($trashid == $link_details[
'majorid'])
continue;
6996 trigger_localised_error(
'SYS0152', E_USER_WARNING, $link_details[
'linkid']);
6997 foreach ($locked as $aid) {
7000 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
7001 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
7005 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
7007 foreach ($locked as $aid) {
7010 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
7011 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
7042 function getPermission($assetid, $permission, $granted=NULL, $and_greater=TRUE, $expand_groups=FALSE, $all_info=FALSE, $collapse_roles=FALSE)
7044 $permission = (int) $permission;
7045 if (!is_null($granted)) $granted = (
bool) $granted;
7049 $id_parts = explode(
':', $assetid);
7051 if (isset($id_parts[1])) {
7052 $real_assetid = $id_parts[0];
7053 $asset = $this->
getAsset($real_assetid);
7055 if (!is_null($asset)) {
7056 if (method_exists($asset,
'getPermission')) {
7057 $ret_val = $asset->getPermission($assetid, $permission, $granted, $and_greater, $expand_groups, $all_info);
7059 $ret_val = $GLOBALS[
'SQ_SYSTEM']->am->getPermission($real_assetid, $permission, $granted, $and_greater, $expand_groups, $all_info);
7067 if (($and_greater || $expand_groups) && $all_info) {
7068 trigger_localised_error(
'SYS0273', E_USER_NOTICE, __CLASS__, __FUNCTION__);
7072 if (!isset($this->_tmp[
'permission_cache'])) {
7073 $this->_tmp[
'permission_cache'] = Array();
7075 if (!isset($this->_tmp[
'permission_cache'][$assetid])) {
7076 $this->_tmp[
'permission_cache'][$assetid] = Array();
7080 $suffix = $collapse_roles ?
'1' :
'0';
7081 $storage_name =(($and_greater) ?
'effective_' :
'').
'permission_'.$permission.
'_'.$suffix;
7082 if (!isset($this->_tmp[
'permission_cache'][$assetid][$storage_name])) {
7086 $table = ($collapse_roles) ?
'ast_perm' :
'vw_ast_perm';
7087 $sql =
' SELECT DISTINCT assetid, userid, granted
7088 FROM '.SQ_TABLE_RUNNING_PREFIX.$table.
' ';
7089 $where =
'assetid = :assetid
7090 AND permission '.(($and_greater) ?
'>= ' :
'= ').
':permission';
7091 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where);
7099 }
catch (Exception $e) {
7100 throw new Exception(
'Unable to get permissions of asset ID #'.$assetid.
' due to database error: '.$e->getMessage());
7104 $this->_tmp[
'permission_cache'][$assetid][$storage_name] = $result;
7109 foreach ($this->_tmp[
'permission_cache'][$assetid][$storage_name] as $data) {
7111 if ($granted === FALSE && $data[
'granted'] !=
'0') {
7113 }
else if ($granted === TRUE && $data[
'granted'] !=
'1') {
7119 $ret_val[$data[
'userid']] = $data[
'granted'];
7125 if ($expand_groups && $data[
'userid']) {
7126 $user = $this->
getAsset($data[
'userid']);
7127 if (!is_null($user)) {
7129 $ret_val = array_merge($ret_val, array_keys($this->
getChildren($user->id, Array(
'user'), FALSE)));
7132 $ret_val[] = $user->id;
7135 $ret_val[] = $data[
'userid'];
7145 return array_unique($ret_val);
7159 $sql =
' SELECT DISTINCT userid, granted, cascades
7160 FROM '.SQ_TABLE_RUNNING_PREFIX.
'ast_perm ';
7161 $where =
'assetid = :assetid AND permission = :permission';
7162 if (!is_null($cascades)) {
7163 $where .=
' AND cascades = :cascades';
7165 if (!is_null($userid)) {
7166 $where .=
' AND userid = :userid';
7168 $where = $GLOBALS[
'SQ_SYSTEM']->constructRollbackWhereClause($where);
7174 if (!is_null($cascades)) {
7177 if (!is_null($userid)) {
7181 }
catch (Exception $e) {
7182 throw new Exception(
'Unable to get set permissions of asset ID #'.$assetid.
' due to database error: '.$e->getMessage());
7203 function setPermission($assetid, $userid, $permission, $granted, $cascades=TRUE, $force_set=FALSE)
7205 $permission = (int) $permission;
7206 $granted = (bool) $granted;
7207 $db_action =
'insert';
7211 $id_parts = explode(
':', $assetid);
7213 if (isset($id_parts[1])) {
7214 $real_assetid = $id_parts[0];
7215 $asset = $this->
getAsset($real_assetid);
7218 if (is_null($asset))
continue;
7219 if (method_exists($asset,
'setPermission')) {
7220 $ret_val = $asset->setPermission($assetid, $userid, $permission, $granted);
7227 $asset = $this->
getAsset($assetid);
7228 if (is_null($asset))
return FALSE;
7229 if (!$asset->adminAccess(
'permissions')) {
7230 trigger_localised_error(
'SYS0111', E_USER_WARNING, $asset->name);
7235 $current = $this->
getPermission($assetid, $permission, $granted, FALSE, FALSE, FALSE, TRUE);
7236 if (in_array($userid, array_values($current))) {
7239 if (!empty($perm_info)) {
7244 $db_action =
'update';
7249 if (!empty($userid)) {
7251 $user = $this->
getAsset($userid,
'', TRUE);
7253 trigger_localised_error(
'SYS0112', E_USER_WARNING);
7255 }
else if (!($user instanceof
User) && !($user instanceof
User_Group)) {
7256 trigger_localised_error(
'SYS0113', E_USER_WARNING, $user->type());
7259 $user_name = $user->name;
7261 $user_name =
'General Public';
7264 $current = $this->
getPermission($assetid, $permission, !$granted, FALSE, FALSE, FALSE, TRUE);
7265 if (in_array($userid, array_values($current))) {
7267 $db_action =
'update';
7269 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
7270 $perm_name = permission_type_name($permission);
7272 $new_access = ($granted) ?
'grant' :
'revoke';
7273 $current_access = ($granted) ?
'revoked' :
'granted';
7274 trigger_localised_error(
'SYS0123', E_USER_WARNING, $new_access, $perm_name, $user_name, $asset->name, $current_access);
7279 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
7280 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
7284 switch ($db_action) {
7310 cascades = :cascades
7313 AND userid = :userid
7314 AND permission = :permission';
7327 }
catch (Exception $e) {
7328 throw new Exception(
'Unable to '.$db_action.
' permissions for asset "'.$asset->name.
'" (#'.$asset->id.
') due to database error: '.$e->getMessage());
7331 if (!$asset->permissionsUpdated()) {
7332 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
7333 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
7337 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
7338 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
7341 if (isset($this->_tmp[
'permission_cache'][$assetid])) {
7342 unset($this->_tmp[
'permission_cache'][$assetid]);
7346 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
7347 $ms = $GLOBALS[
'SQ_SYSTEM']->getMessagingService();
7350 'perm_name' => permission_type_name($permission),
7351 'asset_name' => $asset->name,
7352 'user_name' => $user_name,
7354 $message = $ms->newMessage(Array(),
'asset.permissions.'.($granted ?
'grant' :
'deny'), $msg_reps);
7355 $message->parameters[
'assetid'] = $asset->id;
7359 $changed_array = Array(
7360 'perm_name' => permission_type_name($permission),
7361 'asset_name' => $asset->name,
7362 'user_name' => $user_name,
7364 $em = $GLOBALS[
'SQ_SYSTEM']->getEventManager();
7365 $em->broadcastEvent($asset,
'PermissionChange', $changed_array);
7384 $permission = (int) $permission;
7388 $id_parts = explode(
':', $assetid);
7390 if (isset($id_parts[1])) {
7391 $real_assetid = $id_parts[0];
7392 $asset = $this->
getAsset($real_assetid);
7394 if (is_null($asset))
continue;
7397 if (method_exists($asset,
'deletePermission')) {
7398 $ret_val = $asset->deletePermission($assetid, $userid, $permission);
7405 $asset = $this->
getAsset($assetid);
7406 if (is_null($asset))
return FALSE;
7407 if (!$asset->adminAccess(
'permissions')) {
7408 trigger_localised_error(
'SYS0104', E_USER_WARNING, $asset->name);
7413 if (!empty($userid)) {
7418 $user_info = $this->
getAssetInfo(Array($userid),
'user', FALSE);
7421 if (empty($user_info)) {
7422 $user_name =
'Unknown User';
7424 $user_name = $user_info[$userid][
'name'];
7427 $user_name =
'General Public';
7430 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
7433 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
7436 $bind_vars = Array (
7437 'userid' => $userid,
7438 'permission' => $permission,
7439 'assetid' => $assetid,
7442 }
catch (Exception $e) {
7443 throw new Exception(
'Unable to delete permission '.$permission.
' of userid #'.$userid.
' on assetid #'.$assetid .
' due to the following database error.'.$e->getMessage());
7446 if (!$asset->permissionsUpdated()) {
7447 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
7448 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
7452 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
7453 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
7456 if (isset($this->_tmp[
'permission_cache'][$assetid])) {
7457 unset($this->_tmp[
'permission_cache'][$assetid]);
7461 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
7462 $ms = $GLOBALS[
'SQ_SYSTEM']->getMessagingService();
7465 'perm_name' => permission_type_name($permission),
7466 'asset_name' => $asset->name,
7467 'user_name' => $user_name,
7469 $message = $ms->newMessage(Array(),
'asset.permissions.delete', $msg_reps);
7470 $message->parameters[
'assetid'] = $asset->id;
7474 $changed_array = Array(
7475 'perm_name' => permission_type_name($permission),
7476 'asset_name' => $asset->name,
7477 'user_name' => $user_name,
7479 $em = $GLOBALS[
'SQ_SYSTEM']->getEventManager();
7480 $em->broadcastEvent($asset,
'PermissionChange', $changed_array);
7510 function getRole($assetid=NULL, $roleid=NULL, $userid=NULL, $include_assetid=FALSE, $include_globals=FALSE, $expand_groups=FALSE, $inc_dependants=TRUE, $include_parents=FALSE, $type_codes=Array(), $strict_type_code=TRUE)
7512 if (SQ_CONF_ENABLE_ROLES_PERM_SYSTEM ==
'0' && SQ_CONF_ENABLE_ROLES_WF_SYSTEM ==
'0')
return Array();
7517 if (!is_null($assetid)) {
7518 $where[] =
'r.assetid = :assetid';
7521 if (!is_null($roleid)) {
7522 $where[] =
'r.roleid = :roleid';
7525 if (!is_null($userid)) {
7527 if($include_parents && !empty($userid)) {
7528 $parents = $GLOBALS[
'SQ_SYSTEM']->am->getParents($userid,
'user_group', FALSE);
7529 foreach ($parents as $usergroupid => $type_code) {