3 # FILE: MetadataSchema.php
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2012-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis
15 # ---- PUBLIC INTERFACE --------------------------------------------------
17 # metadata field base types
18 # (must parallel MetadataFields.FieldType declaration in install/CreateTables.sql
19 # and MetadataField::$FieldTypeDBEnums declaration below)
36 # types of field ordering
59 # names used for display and edit orders
74 $this->
Id = $SchemaId;
76 # set up item factory base class
78 "MetadataField",
"MetadataFields",
"FieldId",
"FieldName", FALSE,
79 "SchemaId = ".intval($this->
Id()));
81 # load schema info from database
82 $this->DB->Query(
"SELECT * FROM MetadataSchemas"
83 .
" WHERE SchemaId = ".intval($SchemaId));
84 if ($this->DB->NumRowsSelected() < 1)
86 throw new Exception(
"Attempt to load metadata schema with "
87 .
" invalid ID (".$SchemaId.
").");
89 $Info = $this->DB->FetchRow();
90 $this->
Name = $Info[
"Name"];
96 # start with field info caching enabled
97 $this->CachingOn = TRUE;
111 # retrieve all constants for class
112 $Reflect =
new ReflectionClass(get_class());
113 $Constants = $Reflect->getConstants();
116 foreach ($Constants as $CName => $CValue)
118 # if value matches and prefix (if supplied) matches
119 if (($CValue == $Value)
120 && (($Prefix === NULL) || (strpos($CName, $Prefix) === 0)))
122 # return name to caller
127 # report to caller that no matching constant was found
150 $ResourceName = NULL)
152 # supply privilege settings if none provided
153 if ($AuthorPrivs === NULL) { $AuthorPrivs =
new PrivilegeSet(); }
154 if ($EditPrivs === NULL) { $EditPrivs =
new PrivilegeSet(); }
155 if ($ViewPrivs === NULL) { $ViewPrivs =
new PrivilegeSet(); }
157 # add schema to database
159 if (strtoupper($Name) ==
"DEFAULT")
161 $Id = self::SCHEMAID_DEFAULT;
163 elseif (strtoupper($Name) ==
"USER")
165 $Id = self::SCHEMAID_USER;
169 $Id =
$DB->Query(
"SELECT SchemaId FROM MetadataSchemas"
170 .
" ORDER BY SchemaId DESC LIMIT 1",
"SchemaId") + 1;
172 $DB->Query(
"INSERT INTO MetadataSchemas"
173 .
" (SchemaId, Name, ViewPage,"
174 .
" AuthoringPrivileges, EditingPrivileges, ViewingPrivileges)"
175 .
" VALUES (".intval($Id).
","
176 .
"'".addslashes($Name).
"',"
177 .
"'".mysql_escape_string($ViewPage).
"',"
178 .
"'".mysql_escape_string($AuthorPrivs->Data()).
"',"
179 .
"'".mysql_escape_string($EditPrivs->Data()).
"',"
180 .
"'".mysql_escape_string($ViewPrivs->Data()).
"')");
182 # construct the new schema
185 # set schema name if none supplied
188 $Schema->Name(
"Metadata Schema ".$Id);
191 # set the resource name if one is supplied
192 if (!is_null($ResourceName))
194 $Schema->ResourceName($ResourceName);
197 # Nudge the Edit and Display order so that they will exist
198 $Schema->GetEditOrder();
199 $Schema->GetDisplayOrder();
201 # return the new schema
213 $DB->Query(
"SELECT * FROM MetadataSchemas"
214 .
" WHERE SchemaId = ".intval($SchemaId));
215 return (
$DB->NumRowsSelected() > 0) ? TRUE : FALSE;
225 # return value to caller
234 function Name($NewValue = NULL)
236 # set new name if one supplied
237 if ($NewValue !== NULL)
239 $this->DB->Query(
"UPDATE MetadataSchemas"
240 .
" SET Name = '".addslashes($NewValue).
"'"
241 .
" WHERE SchemaId = '".intval($this->
Id).
"'");
242 $this->
Name = $NewValue;
245 # get the name if it hasn't been cached yet
246 if (!isset($this->
Name))
248 $this->
Name = $this->DB->Query(
"SELECT * FROM MetadataSchemas"
249 .
" WHERE SchemaId = '".intval($this->
Id).
"'",
"Name");
252 # return current value to caller
263 # set new resource name if one supplied
264 if ($NewValue !== NULL)
267 UPDATE MetadataSchemas
268 SET ResourceName = '".addslashes($NewValue).
"'
269 WHERE SchemaId = '".intval($this->
Id).
"'");
273 # get the name if it hasn't been cached yet
277 SELECT * FROM MetadataSchemas
278 WHERE SchemaId = '".intval($this->
Id).
"'",
281 # use the default resource name if one isn't set
288 # return current value to caller
289 return $this->ResourceName;
299 # set new viewing page if one supplied
300 if ($NewValue !== NULL)
302 $this->DB->Query(
"UPDATE MetadataSchemas"
303 .
" SET ViewPage = '".addslashes($NewValue).
"'"
304 .
" WHERE SchemaId = '".intval($this->
Id).
"'");
308 # get the view page if it hasn't been cached yet
311 $this->
ViewPage = $this->DB->Query(
"SELECT * FROM MetadataSchemas"
312 .
" WHERE SchemaId = '".intval($this->
Id).
"'",
"ViewPage");
315 # return current value to caller
316 return $this->ViewPage;
326 # if new privileges supplied
327 if ($NewValue !== NULL)
329 # store new privileges in database
330 $this->DB->Query(
"UPDATE MetadataSchemas"
331 .
" SET AuthoringPrivileges = '"
332 .mysql_escape_string($NewValue->Data()).
"'"
333 .
" WHERE SchemaId = ".intval($this->
Id));
337 # return current value to caller
338 return $this->AuthoringPrivileges;
348 # if new privileges supplied
349 if ($NewValue !== NULL)
351 # store new privileges in database
352 $this->DB->Query(
"UPDATE MetadataSchemas"
353 .
" SET EditingPrivileges = '"
354 .mysql_escape_string($NewValue->Data()).
"'"
355 .
" WHERE SchemaId = ".intval($this->
Id));
359 # return current value to caller
360 return $this->EditingPrivileges;
370 # if new privileges supplied
371 if ($NewValue !== NULL)
373 # store new privileges in database
374 $this->DB->Query(
"UPDATE MetadataSchemas"
375 .
" SET ViewingPrivileges = '"
376 .mysql_escape_string($NewValue->Data()).
"'"
377 .
" WHERE SchemaId = ".intval($this->
Id));
381 # return current value to caller
382 return $this->ViewingPrivileges;
394 # get authoring privilege set for schema
397 # get privilege set for user
398 $UserPrivs = $User->Privileges();
400 # user can author if privileges are greater than resource set
401 $CanAuthor = $UserPrivs->IsGreaterThan($AuthorPrivs);
403 # allow plugins to modify result of permission check
404 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
405 "EVENT_RESOURCE_AUTHOR_PERMISSION_CHECK", array(
408 "CanAuthor" => $CanAuthor));
409 $CanAuthor = $SignalResult[
"CanAuthor"];
411 # report back to caller whether user can author field
422 # get the query/GET parameters for the view page
423 $Query = parse_url($this->
ViewPage(), PHP_URL_QUERY);
425 # the URL couldn't be parsed
426 if (!is_string($Query))
431 # parse the GET parameters out of the query string
432 $GetVars = ParseQueryString($Query);
434 # search for the ID parameter
435 $Result = array_search(
"\$ID", $GetVars);
437 return $Result !== FALSE ? $Result : NULL;
454 # get the query/GET parameters for the view page
455 $Query = parse_url($this->
ViewPage(), PHP_URL_QUERY);
457 # can't perform matching if the URL couldn't be parsed
458 if (!is_string($Query))
463 # parse the GET parameters out of the query string
464 $GetVars = ParseQueryString($Query);
466 # now, get the query/GET parameters from the path given
467 $PathQuery = parse_url($Path, PHP_URL_QUERY);
469 # can't perform matching if the URL couldn't be parsed
470 if (!is_string($PathQuery))
475 # parse the GET parameters out of the path's query string
476 $PathGetVars = ParseQueryString($PathQuery);
478 # make sure the given path GET parameters contain at least the GET
479 # parameters from the view page and that all non-variable parameters are
480 # equal. the path GET parameters may contain more, which is okay
481 foreach ($GetVars as $GetVarName => $GetVarValue)
483 # there's a required parameter that is not included in the path GET
485 if (!array_key_exists($GetVarName, $PathGetVars))
490 # require the path's value to be equal to the view page's value if
491 # the view page's value is not a variable,
492 if ($PathGetVars[$GetVarName] != $GetVarValue
493 && (!strlen($GetVarValue) || $GetVarValue{0} !=
"$"))
499 # the path matches the view page path
509 $this->CachingOn = $NewValue;
521 function AddField($FieldName, $FieldType, $Optional = TRUE, $DefaultValue = NULL)
523 # clear any existing error messages
524 if (array_key_exists(__METHOD__, $this->ErrorMsgs))
525 { unset($this->ErrorMsgs[__METHOD__]); }
531 $FieldName, $Optional, $DefaultValue);
533 catch (Exception $Exception)
535 $this->ErrorMsgs[__METHOD__][] = $Exception->getMessage();
539 # return new field to caller
557 # clear loading status
559 if (array_key_exists(__METHOD__, $this->ErrorMsgs))
560 { unset($this->ErrorMsgs[__METHOD__]); }
562 # check that file exists and is readable
563 if (!file_exists($FileName))
565 $this->ErrorMsgs[__METHOD__][] =
"Could not find XML file '"
569 elseif (!is_readable($FileName))
571 $this->ErrorMsgs[__METHOD__][] =
"Could not read from XML file '"
577 libxml_use_internal_errors(TRUE);
578 $XmlData = simplexml_load_file($FileName);
579 $Errors = libxml_get_errors();
580 libxml_use_internal_errors(FALSE);
583 if ($XmlData === FALSE)
585 # retrieve XML error messages
586 foreach ($Errors as $Err)
588 $ErrType = ($Err->level == LIBXML_ERR_WARNING) ?
"Warning"
589 : (($Err->level == LIBXML_ERR_WARNING) ?
"Error"
591 $this->ErrorMsgs[__METHOD__][] =
"XML ".$ErrType.
": ".$Err->message
592 .
" (".$Err->file.
":".$Err->line.
",".$Err->column.
")";
595 # else if no metadata fields found record error message
596 elseif (!count($XmlData->MetadataField))
598 $this->ErrorMsgs[__METHOD__][] =
"No metadata fields found.";
600 # else process metadata fields
603 # for each metadata field entry found
606 foreach ($XmlData->MetadataField as $FieldXml)
610 # pull out field type if present
611 if (isset($FieldXml->Type))
613 $FieldType =
"MetadataSchema::".$FieldXml->Type;
614 if (!defined($FieldType))
616 $FieldType =
"MetadataSchema::MDFTYPE_"
617 .strtoupper(preg_replace(
"/\\s+/",
"",
622 # if required values are missing
623 if (!isset($FieldXml->Name) || !isset($FieldXml->Type)
624 || !defined($FieldType))
626 # add error message about required value missing
627 if (!isset($FieldXml->Name))
629 $this->ErrorMsgs[__METHOD__][] =
630 "Field name not found (MetadataField #"
635 $this->ErrorMsgs[__METHOD__][] =
636 "Valid type not found for field '"
637 .$FieldXml->Name.
"' (MetadataField #"
641 # else if there is not already a field with this name
642 elseif (!$this->
NameIsInUse(trim($FieldXml->Name)))
645 $Field = $this->
AddField($FieldXml->Name, constant($FieldType));
647 # if field creation failed
650 # add any error message to our error list
652 foreach ($ErrorMsgs as $Msg)
654 $this->ErrorMsgs[__METHOD__][] =
660 # add field to list of created fields
663 # for other field attributes
664 foreach ($FieldXml as $MethodName => $Value)
666 # if tags look valid and have not already been set
667 if (method_exists($Field, $MethodName)
668 && ($MethodName !=
"Name")
669 && ($MethodName !=
"Type"))
671 # if tag indicates privilege set
672 if (preg_match(
"/^[a-z]+Privileges\$/i",
675 # save element for later processing
676 $PrivilegesToSet[$Field->Id()][$MethodName] = $Value;
680 # condense down any extraneous whitespace
681 $Value = preg_replace(
"/\s+/",
" ", trim($Value));
683 # set value for field
684 $Field->$MethodName($Value);
689 # save the temp ID so that any privileges to set can be
690 # mapped to the actual ID when the field is made
692 $TempId = $Field->Id();
694 # make new field permanent
695 $Field->IsTempItem(FALSE);
697 # map privileges to set to the permanent field ID
698 if (isset($PrivilegesToSet) &&
699 isset($PrivilegesToSet[$TempId]) )
701 # copy the privileges over
702 $PrivilegesToSet[$Field->Id()] =
703 $PrivilegesToSet[$TempId];
705 # remove the values for the temp ID
706 unset($PrivilegesToSet[$TempId]);
712 # if we have privileges to set
713 if (isset($PrivilegesToSet))
715 # for each field with privileges
716 foreach ($PrivilegesToSet as $FieldId => $Privileges)
718 # load the field for which to set the privileges
721 # for each set of privileges for field
722 foreach ($Privileges as $MethodName => $Value)
724 # convert privilege value
725 $Value = $this->ConvertXmlToPrivilegeSet($Value);
727 # if conversion failed
730 # add resulting error messages to our list
732 "ConvertXmlToPrivilegeSet");
733 foreach ($ErrorMsgs as $Msg)
735 $this->ErrorMsgs[__METHOD__][] =
736 $Msg.
" (ConvertXmlToPrivilegeSet)";
741 # set value for field
742 $Field->$MethodName($Value);
748 # if errors were found during creation
749 if (array_key_exists(__METHOD__, $this->ErrorMsgs) || $TestRun)
751 # remove any fields that were created
760 # report success or failure based on whether errors were recorded
761 return (array_key_exists(__METHOD__, $this->ErrorMsgs)) ? FALSE : TRUE;
771 return $this->NewFields;
785 if ($Method === NULL)
787 return $this->ErrorMsgs;
791 if (!method_exists($this, $Method))
793 throw new Exception(
"Error messages requested for non-existent"
794 .
" method (".$Method.
").");
796 return array_key_exists(__CLASS__.
"::".$Method, $this->ErrorMsgs)
797 ? $this->ErrorMsgs[__CLASS__.
"::".$Method] : array();
812 # assume field addition will fail
813 $Field = self::MDFSTAT_ERROR;
815 # add XML prefixes if needed
817 if (!preg_match(
"/^<\?xml/i", $Xml))
819 if (!preg_match(
"/^<document>/i", $Xml))
821 $Xml =
"<document>".$Xml.
"</document>";
823 $Xml =
"<?xml version='1.0'?".
">".$Xml;
827 $XmlData = simplexml_load_string($Xml);
829 # if required values are present
830 if (is_object($XmlData)
831 && isset($XmlData->Name)
832 && isset($XmlData->Type)
833 && constant(
"MetadataSchema::".$XmlData->Type))
835 # create the metadata field
838 constant(
"MetadataSchema::".$XmlData->Type));
840 # if field creation succeeded
843 # for other field attributes
844 foreach ($XmlData as $MethodName => $Value)
846 # if they look valid and have not already been set
847 if (method_exists($Field, $MethodName)
848 && ($MethodName !=
"Name")
849 && ($MethodName !=
"Type"))
851 # if tag indicates privilege set
852 if (preg_match(
"/^[a-z]+Privileges\$/i",
855 # save element for later processing
856 $PrivilegesToSet[$MethodName] = $Value;
860 # condense down any extraneous whitespace
861 $Value = preg_replace(
"/\s+/",
" ", trim($Value));
863 # set value for field
864 $Field->$MethodName($Value);
869 # make new field permanent
870 $Field->IsTempItem(FALSE);
872 # if we have privileges to set
873 if (isset($PrivilegesToSet))
875 # for each set of privileges for field
876 foreach ($PrivilegesToSet as $MethodName => $Value)
878 # convert privilege value
879 $Value = $this->ConvertXmlToPrivilegeSet($Value);
881 # if conversion failed
884 # add resulting error messages to our list
886 "ConvertXmlToPrivilegeSet");
887 foreach ($ErrorMsgs as $Msg)
889 $this->ErrorMsgs[__METHOD__][] =
890 $Msg.
" (ConvertXmlToPrivilegeSet)";
895 # set value for field
896 $Field->$MethodName($Value);
903 # return new field (if any) to caller
918 $AF->SignalEvent(
"EVENT_PRE_FIELD_DELETE",
919 array(
"FieldId" => $FieldId) );
939 # if caching is off or field is not already loaded
940 if (($this->CachingOn != TRUE) || !isset($Fields[$FieldId]))
947 catch (Exception $Exception)
949 $Fields[$FieldId] = NULL;
953 # return field to caller
954 return $Fields[$FieldId];
966 return ($FieldId === NULL) ? NULL : $this->
GetField($FieldId);
978 return ($FieldId === NULL) ? NULL : $this->
GetField($FieldId);
990 static $FieldIdsByName;
992 # if caching is off or field ID is already loaded
993 if (($this->CachingOn != TRUE) || !isset($FieldIdsByName[$this->
Id][$FieldName]))
995 # retrieve field ID from DB
996 $Condition = $IgnoreCase
997 ?
"WHERE LOWER(FieldName) = '".addslashes(strtolower($FieldName)).
"'"
998 :
"WHERE FieldName = '".addslashes($FieldName).
"'";
999 $Condition .=
" AND SchemaId = ".intval($this->
Id);
1000 $FieldIdsByName[$this->Id][$FieldName] = $this->DB->Query(
1001 "SELECT FieldId FROM MetadataFields ".$Condition,
"FieldId");
1004 return $FieldIdsByName[$this->Id][$FieldName];
1016 static $FieldIdsByLabel;
1018 # if caching is off or field ID is already loaded
1019 if (($this->CachingOn != TRUE) || !isset($FieldIdsByLabel[$FieldLabel]))
1021 # retrieve field ID from DB
1022 $Condition = $IgnoreCase
1023 ?
"WHERE LOWER(Label) = '".addslashes(strtolower($FieldLabel)).
"'"
1024 :
"WHERE Label = '".addslashes($FieldLabel).
"'";
1025 $Condition .=
" AND SchemaId = ".intval($this->
Id);
1026 $FieldIdsByLabel[$FieldLabel] = $this->DB->Query(
1027 "SELECT FieldId FROM MetadataFields ".$Condition,
"FieldId");
1030 return $FieldIdsByLabel[$FieldLabel];
1054 $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
1056 # create empty array to pass back
1059 # for each field type in database
1060 $this->DB->Query(
"SELECT FieldId, FieldType FROM MetadataFields"
1061 .
" WHERE SchemaId = ".intval($this->
Id)
1062 .(!$IncludeDisabledFields ?
" AND Enabled != 0" :
"")
1063 .(!$IncludeTempFields ?
" AND FieldId >= 0" :
""));
1064 while ($Record = $this->DB->FetchRow())
1066 # if field type is known
1069 # if no specific type requested or if field is of requested type
1070 if (($FieldTypes == NULL)
1074 # create field object and add to array to be passed back
1075 $Fields[$Record[
"FieldId"]] = $this->
GetField($Record[
"FieldId"]);
1080 # if field sorting requested
1081 if ($OrderType !== NULL)
1083 # update field comparison ordering if not set yet
1089 $this->FieldCompareType = $OrderType;
1091 # sort field array by requested order type
1092 uasort($Fields, array($this,
"CompareFieldOrder"));
1095 # return array of field objects to caller
1114 $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
1116 $Fields = $this->
GetFields($FieldTypes, $OrderType,
1117 $IncludeDisabledFields, $IncludeTempFields);
1119 $FieldNames = array();
1120 foreach($Fields as $Field)
1122 $FieldNames[$Field->Id()] = $Field->Name();
1145 $SelectedFieldId = NULL, $IncludeNullOption = TRUE,
1146 $AddEntries = NULL, $AllowMultiple = FALSE)
1148 # retrieve requested fields
1151 # transform field names to labels
1152 foreach ($FieldNames as $FieldId => $FieldName)
1154 $FieldNames[$FieldId] = $this->
GetField($FieldId)->GetDisplayName();
1157 # begin HTML option list
1158 $Html =
"<select id=\"".$OptionListName.
"\" name=\"".$OptionListName.
"\"";
1160 # if multiple selections should be allowed
1163 $Html .=
" multiple=\"multiple\"";
1168 if ($IncludeNullOption)
1170 $Html .=
"<option value=\"\">--</option>\n";
1173 # make checking for IDs simpler
1174 if (!is_array($SelectedFieldId))
1176 $SelectedFieldId = array($SelectedFieldId);
1179 # for each metadata field
1180 foreach ($FieldNames as $Id => $Name)
1182 # add entry for field to option list
1183 $Html .=
"<option value=\"".$Id.
"\"";
1184 if (in_array($Id, $SelectedFieldId)) { $Html .=
" selected"; }
1185 $Html .=
">".htmlspecialchars($Name).
"</option>\n";
1188 # if additional entries were requested
1191 foreach ($AddEntries as $Value => $Label)
1193 $Html .=
"<option value=\"".$Value.
"\"";
1194 if (in_array($Value, $SelectedFieldId))
1196 $Html .=
" selected";
1198 $Html .=
">".htmlspecialchars($Label).
"</option>\n";
1202 # end HTML option list
1203 $Html .=
"</select>\n";
1205 # return constructed HTML to caller
1235 # sanitize qualifier ID or grab it from object
1236 $QualifierIdOrObject = is_object($QualifierIdOrObject)
1237 ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
1239 # delete intersection records from database
1240 $this->DB->Query(
"DELETE FROM FieldQualifierInts"
1241 .
" WHERE QualifierId = ".$QualifierIdOrObject);
1251 # sanitize qualifier ID or grab it from object
1252 $QualifierIdOrObject = is_object($QualifierIdOrObject)
1253 ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
1255 # determine whether any fields use qualifier as default
1256 $DefaultCount = $this->DB->Query(
"SELECT COUNT(*) AS RecordCount"
1257 .
" FROM MetadataFields"
1258 .
" WHERE DefaultQualifier = ".$QualifierIdOrObject,
1261 # determine whether any fields are associated with qualifier
1262 $AssociationCount = $this->DB->Query(
"SELECT COUNT(*) AS RecordCount"
1263 .
" FROM FieldQualifierInts"
1264 .
" WHERE QualifierId = ".$QualifierIdOrObject,
1267 # report whether qualifier is in use based on defaults and associations
1268 return (($DefaultCount + $AssociationCount) > 0) ? TRUE : FALSE;
1286 if ($FieldId !== NULL)
1288 self::$FieldMappings[$MappedName] = $FieldId;
1290 return isset(self::$FieldMappings[$MappedName])
1291 ? self::$FieldMappings[$MappedName] : NULL;
1304 foreach (self::$FieldMappings as $MappedName => $MappedFieldId)
1306 if ($MappedFieldId == $FieldId)
1324 return (self::StdNameToFieldMapping($MappedName) == NULL) ? NULL
1337 return self::StdNameToFieldMapping($MappedName);
1348 $this->DB->Query(
"SELECT * FROM MetadataFields"
1349 .
" WHERE Owner IS NOT NULL AND LENGTH(Owner) > 0"
1350 .
" AND SchemaId = ".intval($this->
Id));
1352 while (FALSE !== ($Row = $this->DB->FetchRow()))
1354 $FieldId = $Row[
"FieldId"];
1355 $Fields[$FieldId] = $this->
GetField($FieldId);
1371 # fetch the IDs all of the metadata schemas
1372 $Database->Query(
"SELECT * FROM MetadataSchemas");
1373 $SchemaIds = $Database->FetchColumn(
"SchemaId");
1375 # construct objects from the IDs
1376 foreach ($SchemaIds as $SchemaId)
1391 if (is_callable($Callback))
1393 self::$OwnerListRetrievalFunction = $Callback;
1404 # if an owner list retrieval function and default schema exists
1405 if (self::$OwnerListRetrievalFunction
1406 && self::SchemaExistsWithId(self::SCHEMAID_DEFAULT))
1408 # retrieve the list of owners that currently exist
1409 $OwnerList = call_user_func(self::$OwnerListRetrievalFunction);
1411 # an array is expected
1412 if (is_array($OwnerList))
1416 # get each metadata field that is owned by a plugin
1417 $OwnedFields = $Schema->GetOwnedFields();
1419 # loop through each owned field
1420 foreach ($OwnedFields as $OwnedField)
1422 # the owner of the current field
1423 $Owner = $OwnedField->Owner();
1425 # if the owner of the field is in the list of owners that
1426 # currently exist, i.e., available plugins
1427 if (in_array($Owner, $OwnerList))
1429 # enable the field and reset its "enable on owner return"
1430 # flag if the "enable on owner return" flag is currently
1431 # set to true. in other words, re-enable the field since
1432 # the owner has returned to the list of existing owners
1433 if ($OwnedField->EnableOnOwnerReturn())
1435 $OwnedField->Enabled(TRUE);
1436 $OwnedField->EnableOnOwnerReturn(FALSE);
1440 # if the owner of the field is *not* in the list of owners
1441 # that currently exist, i.e., available plugins
1444 # first, see if the field is currently enabled since it
1445 # will determine whether the field is re-enabled when
1446 # the owner becomes available again
1447 $Enabled = $OwnedField->Enabled();
1449 # if the field is enabled, set its "enable on owner
1450 # return" flag to true and disable the field. nothing
1451 # needs to be done if the field is already disabled
1454 $OwnedField->EnableOnOwnerReturn($Enabled);
1455 $OwnedField->Enabled(FALSE);
1473 $this->FieldCompareDisplayOrder[$Field->Id()] = $Index++;
1480 $this->FieldCompareEditOrder[$Field->Id()] = $Index++;
1490 # try to fetch an existing display order
1493 self::ORDER_DISPLAY_NAME);
1495 # if the order doesn't exist
1496 if (is_null($DisplayOrder))
1498 $OldId = $GLOBALS[
"SysConfig"]->FieldDisplayFolder();
1500 # if the older version of MetadataFieldOrder was in use
1501 if ($OldId && $this->
Id() == self::SCHEMAID_DEFAULT)
1503 # add an entry for the existing folder
1505 INSERT INTO MetadataFieldOrders
1506 SET SchemaId = '".addslashes($this->
Id()).
"',
1507 OrderId = '".addslashes($OldId).
"',
1508 OrderName = '".addslashes(self::ORDER_DISPLAY_NAME).
"'");
1514 # otherwise, just create a new order
1519 self::ORDER_DISPLAY_NAME,
1520 self::GetOrderForUpgrade($this, self::ORDER_DISPLAY_NAME));
1524 return $DisplayOrder;
1533 # try to fetch an existing edit order
1536 self::ORDER_EDIT_NAME);
1538 # if the order doesn't exist
1539 if (is_null($EditOrder))
1541 $OldId = $GLOBALS[
"SysConfig"]->FieldEditFolder();
1543 # if the older version of MetadataFieldOrder was in use
1544 if ($OldId && $this->
Id() == self::SCHEMAID_DEFAULT)
1546 # add an entry for the existing folder
1548 INSERT INTO MetadataFieldOrders
1549 SET SchemaId = '".addslashes($this->
Id()).
"',
1550 OrderId = '".addslashes($OldId).
"',
1551 OrderName = '".addslashes(self::ORDER_EDIT_NAME).
"'");
1557 # otherwise, just create a new order
1562 self::ORDER_EDIT_NAME,
1563 self::GetOrderForUpgrade($this, self::ORDER_EDIT_NAME));
1590 return ($FieldA->GetDisplayName() < $FieldB->GetDisplayName()) ? -1 : 1;
1603 $PositionA = GetArrayValue($Order, $FieldA->Id(), 0);
1604 $PositionB = GetArrayValue($Order, $FieldB->Id(), 0);
1606 return $PositionA < $PositionB ? -1 : 1;
1619 # don't do an upgrade for non-default schemas
1620 if ($Schema->
Id() !== self::SCHEMAID_DEFAULT)
1625 # get the default display order
1626 if ($Name == self::ORDER_DISPLAY_NAME)
1628 # try to get the order from the database and, failing that, use the
1629 # defaults in the class
1630 $Rows = self::GetRowsForUpgrade(self::MDFORDER_DISPLAY);
1631 return count($Rows) ? $Rows: self::$DefaultDisplayOrder;
1634 # get the default edit order
1635 if ($Name == self::ORDER_EDIT_NAME)
1637 # try to get the order from the database and, failing that, use the
1638 # defaults in the class
1639 $Rows = self::GetRowsForUpgrade(self::MDFORDER_EDITING);
1640 return count($Rows) ? $Rows: self::$DefaultEditOrder;
1643 # otherwise make no assumptions about the order
1658 # temporarily suppress errors
1662 # see if the old columns exist
1663 $Handle = $Database->Query(
"
1664 SELECT EditingOrderPosition
1668 # the columns do not exist so an upgrade cannot be performed
1669 if ($Handle === FALSE)
1674 # determine which column to use for ordering
1676 ?
"DisplayOrderPosition" :
"EditingOrderPosition";
1678 # query for the fields in their proper order
1683 ORDER BY ".$Column.
" ASC");
1685 # restore the earlier error setting
1688 # return the resulting field IDs
1689 return $Database->FetchColumn(
"FieldId");
1834 # ---- PRIVATE INTERFACE -------------------------------------------------
1838 private $ResourceName;
1839 private $AuthoringPrivileges;
1840 private $EditingPrivileges;
1841 private $ViewingPrivileges;
1843 private $FieldCompareType;
1845 private $NewFields = array();
1846 private $ErrorMsgs = array();
1847 private static $FieldMappings;
1867 private function ConvertXmlToPrivilegeSet($Xml)
1869 # clear any existing errors
1870 if (array_key_exists(__METHOD__, $this->ErrorMsgs))
1871 { unset($this->ErrorMsgs[__METHOD__]); }
1873 # create new privilege set
1876 # for each XML child
1877 foreach ($Xml as $Tag => $Value)
1879 # take action based on element name
1882 case "PrivilegeSet":
1883 # convert child data to new set
1884 $NewSet = $this->ConvertXmlToPrivilegeSet($Value);
1886 # add new set to our privilege set
1887 $PrivSet->AddSet($NewSet);
1890 case "AddCondition":
1891 # start with default values for optional parameters
1892 unset($ConditionField);
1893 $ConditionValue = NULL;
1894 $ConditionOperator =
"==";
1896 # pull out parameters
1897 foreach ($Value as $ParamName => $ParamValue)
1899 $ParamValue = trim($ParamValue);
1904 (
string)$ParamValue, TRUE);
1905 if ($ConditionField === NULL)
1907 # record error about unknown field
1908 $this->ErrorMsgs[__METHOD__][] =
1909 "Unknown metadata field name found"
1910 .
" in AddCondition (".$ParamValue.
").";
1918 $ConditionValue = ($ParamValue ==
"NULL")
1919 ? NULL : (
string)$ParamValue;
1923 $ConditionOperator = (string)$ParamValue;
1927 # record error about unknown parameter name
1928 $this->ErrorMsgs[__METHOD__][] =
1929 "Unknown tag found in AddCondition ("
1939 if (!isset($ConditionField))
1941 # record error about no field value
1942 $this->ErrorMsgs[__METHOD__][] =
1943 "No metadata field specified in AddCondition.";
1949 # add conditional to privilege set
1950 $PrivSet->AddCondition($ConditionField,
1951 $ConditionValue, $ConditionOperator);
1955 # strip any excess whitespace off of value
1956 $Value = trim($Value);
1958 # if child looks like valid method name
1959 if (method_exists(
"PrivilegeSet", $Tag))
1961 # convert constants if needed
1962 if (defined($Value)) { $Value = constant($Value); }
1964 # convert booleans if needed
1965 if (strtoupper($Value) ==
"TRUE") { $Value = TRUE; }
1966 elseif (strtoupper($Value) ==
"FALSE") { $Value = FALSE; }
1968 # set value using child data
1969 $PrivSet->$Tag((
string)$Value);
1973 # record error about bad tag
1974 $this->ErrorMsgs[__METHOD__][] =
1975 "Unknown tag encountered (".$Tag.
").";
1984 # return new privilege set to caller
GetHighestItemId($IgnoreSqlCondition=FALSE)
Retrieve highest item ID in use.
SQL database abstraction object with smart query caching.
Set of privileges used to access resource information or other parts of the system.
Common factory class for item manipulation.
NameIsInUse($Name, $IgnoreCase=FALSE)
Check whether item name is currently in use.
static DisplayQueryErrors($NewValue=NULL)
Get/set whether Query() errors will be displayed.
ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName, $ItemNameFieldName=NULL, $OrderOpsAllowed=FALSE, $SqlCondition=NULL)
Class constructor.