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;
119 $ResourceName = NULL)
121 # supply privilege settings if none provided
122 if ($AuthorPrivs === NULL) { $AuthorPrivs =
new PrivilegeSet(); }
123 if ($EditPrivs === NULL) { $EditPrivs =
new PrivilegeSet(); }
124 if ($ViewPrivs === NULL) { $ViewPrivs =
new PrivilegeSet(); }
126 # add schema to database
128 if (strtoupper($Name) ==
"DEFAULT")
130 $Id = self::SCHEMAID_DEFAULT;
132 elseif (strtoupper($Name) ==
"USER")
134 $Id = self::SCHEMAID_USER;
138 $Id =
$DB->Query(
"SELECT SchemaId FROM MetadataSchemas"
139 .
" ORDER BY SchemaId DESC LIMIT 1",
"SchemaId") + 1;
141 $DB->Query(
"INSERT INTO MetadataSchemas"
142 .
" (SchemaId, Name, ViewPage,"
143 .
" AuthoringPrivileges, EditingPrivileges, ViewingPrivileges)"
144 .
" VALUES (".intval($Id).
","
145 .
"'".addslashes($Name).
"',"
146 .
"'".mysql_escape_string($ViewPage).
"',"
147 .
"'".mysql_escape_string($AuthorPrivs->Data()).
"',"
148 .
"'".mysql_escape_string($EditPrivs->Data()).
"',"
149 .
"'".mysql_escape_string($ViewPrivs->Data()).
"')");
151 # construct the new schema
154 # set schema name if none supplied
157 $Schema->Name(
"Metadata Schema ".$Id);
160 # set the resource name if one is supplied
161 if (!is_null($ResourceName))
163 $Schema->ResourceName($ResourceName);
166 # return the new schema
178 $DB->Query(
"SELECT * FROM MetadataSchemas"
179 .
" WHERE SchemaId = ".intval($SchemaId));
180 return (
$DB->NumRowsSelected() > 0) ? TRUE : FALSE;
190 # return value to caller
199 function Name($NewValue = NULL)
201 # set new name if one supplied
202 if ($NewValue !== NULL)
204 $this->DB->Query(
"UPDATE MetadataSchemas"
205 .
" SET Name = '".addslashes($NewValue).
"'"
206 .
" WHERE SchemaId = '".intval($this->
Id).
"'");
207 $this->
Name = $NewValue;
210 # get the name if it hasn't been cached yet
211 if (!isset($this->
Name))
213 $this->
Name = $this->DB->Query(
"SELECT * FROM MetadataSchemas"
214 .
" WHERE SchemaId = '".intval($this->
Id).
"'",
"Name");
217 # return current value to caller
228 # set new resource name if one supplied
229 if ($NewValue !== NULL)
232 UPDATE MetadataSchemas
233 SET ResourceName = '".addslashes($NewValue).
"'
234 WHERE SchemaId = '".intval($this->
Id).
"'");
238 # get the name if it hasn't been cached yet
242 SELECT * FROM MetadataSchemas
243 WHERE SchemaId = '".intval($this->
Id).
"'",
246 # use the default resource name if one isn't set
253 # return current value to caller
254 return $this->ResourceName;
264 # set new viewing page if one supplied
265 if ($NewValue !== NULL)
267 $this->DB->Query(
"UPDATE MetadataSchemas"
268 .
" SET ViewPage = '".addslashes($NewValue).
"'"
269 .
" WHERE SchemaId = '".intval($this->
Id).
"'");
273 # get the view page if it hasn't been cached yet
276 $this->
ViewPage = $this->DB->Query(
"SELECT * FROM MetadataSchemas"
277 .
" WHERE SchemaId = '".intval($this->
Id).
"'",
"ViewPage");
280 # return current value to caller
281 return $this->ViewPage;
291 # if new privileges supplied
292 if ($NewValue !== NULL)
294 # store new privileges in database
295 $this->DB->Query(
"UPDATE MetadataSchemas"
296 .
" SET AuthoringPrivileges = '"
297 .mysql_escape_string($NewValue->Data()).
"'"
298 .
" WHERE SchemaId = ".intval($this->
Id));
302 # return current value to caller
303 return $this->AuthoringPrivileges;
313 # if new privileges supplied
314 if ($NewValue !== NULL)
316 # store new privileges in database
317 $this->DB->Query(
"UPDATE MetadataSchemas"
318 .
" SET EditingPrivileges = '"
319 .mysql_escape_string($NewValue->Data()).
"'"
320 .
" WHERE SchemaId = ".intval($this->
Id));
324 # return current value to caller
325 return $this->EditingPrivileges;
335 # if new privileges supplied
336 if ($NewValue !== NULL)
338 # store new privileges in database
339 $this->DB->Query(
"UPDATE MetadataSchemas"
340 .
" SET ViewingPrivileges = '"
341 .mysql_escape_string($NewValue->Data()).
"'"
342 .
" WHERE SchemaId = ".intval($this->
Id));
346 # return current value to caller
347 return $this->ViewingPrivileges;
359 # get authoring privilege set for schema
362 # get privilege set for user
363 $UserPrivs = $User->Privileges();
365 # user can author if privileges are greater than resource set
366 $CanAuthor = $UserPrivs->IsGreaterThan($AuthorPrivs);
368 # allow plugins to modify result of permission check
369 $SignalResult = $GLOBALS[
"AF"]->SignalEvent(
370 "EVENT_RESOURCE_AUTHOR_PERMISSION_CHECK", array(
373 "CanAuthor" => $CanAuthor));
374 $CanAuthor = $SignalResult[
"CanAuthor"];
376 # report back to caller whether user can author field
387 # get the query/GET parameters for the view page
388 $Query = parse_url($this->
ViewPage(), PHP_URL_QUERY);
390 # the URL couldn't be parsed
391 if (!is_string($Query))
396 # parse the GET parameters out of the query string
397 $GetVars = ParseQueryString($Query);
399 # search for the ID parameter
400 $Result = array_search(
"\$ID", $GetVars);
402 return $Result !== FALSE ? $Result : NULL;
419 # get the query/GET parameters for the view page
420 $Query = parse_url($this->
ViewPage(), PHP_URL_QUERY);
422 # can't perform matching if the URL couldn't be parsed
423 if (!is_string($Query))
428 # parse the GET parameters out of the query string
429 $GetVars = ParseQueryString($Query);
431 # now, get the query/GET parameters from the path given
432 $PathQuery = parse_url($Path, PHP_URL_QUERY);
434 # can't perform matching if the URL couldn't be parsed
435 if (!is_string($PathQuery))
440 # parse the GET parameters out of the path's query string
441 $PathGetVars = ParseQueryString($PathQuery);
443 # make sure the given path GET parameters contain at least the GET
444 # parameters from the view page and that all non-variable parameters are
445 # equal. the path GET parameters may contain more, which is okay
446 foreach ($GetVars as $GetVarName => $GetVarValue)
448 # there's a required parameter that is not included in the path GET
450 if (!array_key_exists($GetVarName, $PathGetVars))
455 # require the path's value to be equal to the view page's value if
456 # the view page's value is not a variable,
457 if ($PathGetVars[$GetVarName] != $GetVarValue
458 && (!strlen($GetVarValue) || $GetVarValue{0} !=
"$"))
464 # the path matches the view page path
474 $this->CachingOn = $NewValue;
486 function AddField($FieldName, $FieldType, $Optional = TRUE, $DefaultValue = NULL)
488 # clear any existing error messages
489 if (array_key_exists(__METHOD__, $this->ErrorMsgs))
490 { unset($this->ErrorMsgs[__METHOD__]); }
496 $FieldName, $Optional, $DefaultValue);
498 catch (Exception $Exception)
500 $this->ErrorMsgs[__METHOD__][] = $Exception->getMessage();
504 # return new field to caller
522 # clear loading status
524 if (array_key_exists(__METHOD__, $this->ErrorMsgs))
525 { unset($this->ErrorMsgs[__METHOD__]); }
527 # check that file exists and is readable
528 if (!file_exists($FileName))
530 $this->ErrorMsgs[__METHOD__][] =
"Could not find XML file '"
534 elseif (!is_readable($FileName))
536 $this->ErrorMsgs[__METHOD__][] =
"Could not read from XML file '"
542 libxml_use_internal_errors(TRUE);
543 $XmlData = simplexml_load_file($FileName);
544 $Errors = libxml_get_errors();
545 libxml_use_internal_errors(FALSE);
548 if ($XmlData === FALSE)
550 # retrieve XML error messages
551 foreach ($Errors as $Err)
553 $ErrType = ($Err->level == LIBXML_ERR_WARNING) ?
"Warning"
554 : (($Err->level == LIBXML_ERR_WARNING) ?
"Error"
556 $this->ErrorMsgs[__METHOD__][] =
"XML ".$ErrType.
": ".$Err->message
557 .
" (".$Err->file.
":".$Err->line.
",".$Err->column.
")";
560 # else if no metadata fields found record error message
561 elseif (!count($XmlData->MetadataField))
563 $this->ErrorMsgs[__METHOD__][] =
"No metadata fields found.";
565 # else process metadata fields
568 # for each metadata field entry found
571 foreach ($XmlData->MetadataField as $FieldXml)
575 # pull out field type if present
576 if (isset($FieldXml->Type))
578 $FieldType =
"MetadataSchema::".$FieldXml->Type;
579 if (!defined($FieldType))
581 $FieldType =
"MetadataSchema::MDFTYPE_"
582 .strtoupper(preg_replace(
"/\\s+/",
"",
587 # if required values are missing
588 if (!isset($FieldXml->Name) || !isset($FieldXml->Type)
589 || !defined($FieldType))
591 # add error message about required value missing
592 if (!isset($FieldXml->Name))
594 $this->ErrorMsgs[__METHOD__][] =
595 "Field name not found (MetadataField #"
600 $this->ErrorMsgs[__METHOD__][] =
601 "Valid type not found for field '"
602 .$FieldXml->Name.
"' (MetadataField #"
606 # else if there is not already a field with this name
607 elseif (!$this->
NameIsInUse(trim($FieldXml->Name)))
610 $Field = $this->
AddField($FieldXml->Name, constant($FieldType));
612 # if field creation failed
615 # add any error message to our error list
617 foreach ($ErrorMsgs as $Msg)
619 $this->ErrorMsgs[__METHOD__][] =
625 # add field to list of created fields
628 # for other field attributes
629 foreach ($FieldXml as $MethodName => $Value)
631 # if tags look valid and have not already been set
632 if (method_exists($Field, $MethodName)
633 && ($MethodName !=
"Name")
634 && ($MethodName !=
"Type"))
636 # if tag indicates privilege set
637 if (preg_match(
"/^[a-z]+Privileges\$/i",
640 # save element for later processing
641 $PrivilegesToSet[$Field->Id()][$MethodName] = $Value;
645 # condense down any extraneous whitespace
646 $Value = preg_replace(
"/\s+/",
" ", trim($Value));
648 # set value for field
649 $Field->$MethodName($Value);
654 # save the temp ID so that any privileges to set can be
655 # mapped to the actual ID when the field is made
657 $TempId = $Field->Id();
659 # make new field permanent
660 $Field->IsTempItem(FALSE);
662 # map privileges to set to the permanent field ID
663 if (isset($PrivilegesToSet))
665 # copy the privileges over
666 $PrivilegesToSet[$Field->Id()] =
667 $PrivilegesToSet[$TempId];
669 # remove the values for the temp ID
670 unset($PrivilegesToSet[$TempId]);
676 # if we have privileges to set
677 if (isset($PrivilegesToSet))
679 # for each field with privileges
680 foreach ($PrivilegesToSet as $FieldId => $Privileges)
682 # load the field for which to set the privileges
685 # for each set of privileges for field
686 foreach ($Privileges as $MethodName => $Value)
688 # convert privilege value
689 $Value = $this->ConvertXmlToPrivilegeSet($Value);
691 # if conversion failed
694 # add resulting error messages to our list
696 "ConvertXmlToPrivilegeSet");
697 foreach ($ErrorMsgs as $Msg)
699 $this->ErrorMsgs[__METHOD__][] =
700 $Msg.
" (ConvertXmlToPrivilegeSet)";
705 # set value for field
706 $Field->$MethodName($Value);
712 # if errors were found during creation
713 if (array_key_exists(__METHOD__, $this->ErrorMsgs) || $TestRun)
715 # remove any fields that were created
724 # report success or failure based on whether errors were recorded
725 return (array_key_exists(__METHOD__, $this->ErrorMsgs)) ? FALSE : TRUE;
735 return $this->NewFields;
749 if ($Method === NULL)
751 return $this->ErrorMsgs;
755 if (!method_exists($this, $Method))
757 throw new Exception(
"Error messages requested for non-existent"
758 .
" method (".$Method.
").");
760 return array_key_exists(__CLASS__.
"::".$Method, $this->ErrorMsgs)
761 ? $this->ErrorMsgs[__CLASS__.
"::".$Method] : array();
776 # assume field addition will fail
777 $Field = self::MDFSTAT_ERROR;
779 # add XML prefixes if needed
781 if (!preg_match(
"/^<\?xml/i", $Xml))
783 if (!preg_match(
"/^<document>/i", $Xml))
785 $Xml =
"<document>".$Xml.
"</document>";
787 $Xml =
"<?xml version='1.0'?".
">".$Xml;
791 $XmlData = simplexml_load_string($Xml);
793 # if required values are present
794 if (is_object($XmlData)
795 && isset($XmlData->Name)
796 && isset($XmlData->Type)
797 && constant(
"MetadataSchema::".$XmlData->Type))
799 # create the metadata field
802 constant(
"MetadataSchema::".$XmlData->Type));
804 # if field creation succeeded
807 # for other field attributes
808 foreach ($XmlData as $MethodName => $Value)
810 # if they look valid and have not already been set
811 if (method_exists($Field, $MethodName)
812 && ($MethodName !=
"Name")
813 && ($MethodName !=
"Type"))
815 # if tag indicates privilege set
816 if (preg_match(
"/^[a-z]+Privileges\$/i",
819 # save element for later processing
820 $PrivilegesToSet[$MethodName] = $Value;
824 # condense down any extraneous whitespace
825 $Value = preg_replace(
"/\s+/",
" ", trim($Value));
827 # set value for field
828 $Field->$MethodName($Value);
833 # make new field permanent
834 $Field->IsTempItem(FALSE);
836 # if we have privileges to set
837 if (isset($PrivilegesToSet))
839 # for each set of privileges for field
840 foreach ($PrivilegesToSet as $MethodName => $Value)
842 # convert privilege value
843 $Value = $this->ConvertXmlToPrivilegeSet($Value);
845 # if conversion failed
848 # add resulting error messages to our list
850 "ConvertXmlToPrivilegeSet");
851 foreach ($ErrorMsgs as $Msg)
853 $this->ErrorMsgs[__METHOD__][] =
854 $Msg.
" (ConvertXmlToPrivilegeSet)";
859 # set value for field
860 $Field->$MethodName($Value);
867 # return new field (if any) to caller
899 # if caching is off or field is not already loaded
900 if (($this->CachingOn != TRUE) || !isset($Fields[$FieldId]))
907 catch (Exception $Exception)
909 $Fields[$FieldId] = NULL;
913 # return field to caller
914 return $Fields[$FieldId];
926 return ($FieldId === NULL) ? NULL : $this->
GetField($FieldId);
938 return ($FieldId === NULL) ? NULL : $this->
GetField($FieldId);
950 static $FieldIdsByName;
952 # if caching is off or field ID is already loaded
953 if (($this->CachingOn != TRUE) || !isset($FieldIdsByName[$this->
Id][$FieldName]))
955 # retrieve field ID from DB
956 $Condition = $IgnoreCase
957 ?
"WHERE LOWER(FieldName) = '".addslashes(strtolower($FieldName)).
"'"
958 :
"WHERE FieldName = '".addslashes($FieldName).
"'";
959 $Condition .=
" AND SchemaId = ".intval($this->
Id);
960 $FieldIdsByName[$this->Id][$FieldName] = $this->DB->Query(
961 "SELECT FieldId FROM MetadataFields ".$Condition,
"FieldId");
964 return $FieldIdsByName[$this->Id][$FieldName];
976 static $FieldIdsByLabel;
978 # if caching is off or field ID is already loaded
979 if (($this->CachingOn != TRUE) || !isset($FieldIdsByLabel[$FieldLabel]))
981 # retrieve field ID from DB
982 $Condition = $IgnoreCase
983 ?
"WHERE LOWER(Label) = '".addslashes(strtolower($FieldLabel)).
"'"
984 :
"WHERE Label = '".addslashes($FieldLabel).
"'";
985 $Condition .=
" AND SchemaId = ".intval($this->
Id);
986 $FieldIdsByLabel[$FieldLabel] = $this->DB->Query(
987 "SELECT FieldId FROM MetadataFields ".$Condition,
"FieldId");
990 return $FieldIdsByLabel[$FieldLabel];
1014 $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
1016 # create empty array to pass back
1019 # for each field type in database
1020 if ($IncludeTempFields && $IncludeDisabledFields)
1022 $this->DB->Query(
"SELECT FieldId, FieldType FROM MetadataFields"
1023 .
" WHERE SchemaId = ".intval($this->
Id));
1027 if ($IncludeTempFields)
1029 $this->DB->Query(
"SELECT FieldId, FieldType FROM MetadataFields"
1030 .
" WHERE Enabled != 0"
1031 .
" AND SchemaId = ".intval($this->
Id));
1033 elseif ($IncludeDisabledFields)
1035 $this->DB->Query(
"SELECT FieldId, FieldType FROM MetadataFields"
1036 .
" WHERE FieldId >= 0"
1037 .
" AND SchemaId = ".intval($this->
Id));
1041 $this->DB->Query(
"SELECT FieldId, FieldType FROM MetadataFields"
1042 .
" WHERE FieldId >= 0 AND Enabled != 0"
1043 .
" AND SchemaId = ".intval($this->
Id));
1046 while ($Record = $this->DB->FetchRow())
1048 # if no specific type requested or if field is of requested type
1049 if (($FieldTypes == NULL)
1052 # create field object and add to array to be passed back
1053 $Fields[$Record[
"FieldId"]] = $this->
GetField($Record[
"FieldId"]);
1057 # if field sorting requested
1058 if ($OrderType !== NULL)
1060 # update field comparison ordering if not set yet
1066 $this->FieldCompareType = $OrderType;
1068 # sort field array by requested order type
1069 uasort($Fields, array($this,
"CompareFieldOrder"));
1072 # return array of field objects to caller
1091 $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
1093 $Fields = $this->
GetFields($FieldTypes, $OrderType,
1094 $IncludeDisabledFields, $IncludeTempFields);
1096 $FieldNames = array();
1097 foreach($Fields as $Field)
1099 $FieldNames[$Field->Id()] = $Field->Name();
1122 $SelectedFieldId = NULL, $IncludeNullOption = TRUE,
1123 $AddEntries = NULL, $AllowMultiple = FALSE)
1125 # retrieve requested fields
1128 # transform field names to labels
1129 foreach ($FieldNames as $FieldId => $FieldName)
1131 $FieldNames[$FieldId] = $this->
GetField($FieldId)->GetDisplayName();
1134 # begin HTML option list
1135 $Html =
"<select id=\"".$OptionListName.
"\" name=\"".$OptionListName.
"\"";
1137 # if multiple selections should be allowed
1140 $Html .=
" multiple=\"multiple\"";
1145 if ($IncludeNullOption)
1147 $Html .=
"<option value=\"\">--</option>\n";
1150 # make checking for IDs simpler
1151 if (!is_array($SelectedFieldId))
1153 $SelectedFieldId = array($SelectedFieldId);
1156 # for each metadata field
1157 foreach ($FieldNames as $Id => $Name)
1159 # add entry for field to option list
1160 $Html .=
"<option value=\"".$Id.
"\"";
1161 if (in_array($Id, $SelectedFieldId)) { $Html .=
" selected"; }
1162 $Html .=
">".htmlspecialchars($Name).
"</option>\n";
1165 # if additional entries were requested
1168 foreach ($AddEntries as $Value => $Label)
1170 $Html .=
"<option value=\"".$Value.
"\"";
1171 if (in_array($Value,$SelectedFieldId)) { $Html .=
" selected"; }
1172 $Html .=
">".htmlspecialchars($Label).
"</option>\n";
1176 # end HTML option list
1177 $Html .=
"</select>\n";
1179 # return constructed HTML to caller
1209 # sanitize qualifier ID or grab it from object
1210 $QualifierIdOrObject = is_object($QualifierIdOrObject)
1211 ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
1213 # delete intersection records from database
1214 $this->DB->Query(
"DELETE FROM FieldQualifierInts"
1215 .
" WHERE QualifierId = ".$QualifierIdOrObject);
1225 # sanitize qualifier ID or grab it from object
1226 $QualifierIdOrObject = is_object($QualifierIdOrObject)
1227 ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
1229 # determine whether any fields use qualifier as default
1230 $DefaultCount = $this->DB->Query(
"SELECT COUNT(*) AS RecordCount"
1231 .
" FROM MetadataFields"
1232 .
" WHERE DefaultQualifier = ".$QualifierIdOrObject,
1235 # determine whether any fields are associated with qualifier
1236 $AssociationCount = $this->DB->Query(
"SELECT COUNT(*) AS RecordCount"
1237 .
" FROM FieldQualifierInts"
1238 .
" WHERE QualifierId = ".$QualifierIdOrObject,
1241 # report whether qualifier is in use based on defaults and associations
1242 return (($DefaultCount + $AssociationCount) > 0) ? TRUE : FALSE;
1260 if ($FieldId !== NULL)
1262 self::$FieldMappings[$MappedName] = $FieldId;
1264 return isset(self::$FieldMappings[$MappedName])
1265 ? self::$FieldMappings[$MappedName] : NULL;
1278 foreach (self::$FieldMappings as $MappedName => $MappedFieldId)
1280 if ($MappedFieldId == $FieldId)
1298 return (self::StdNameToFieldMapping($MappedName) == NULL) ? NULL
1311 return self::StdNameToFieldMapping($MappedName);
1322 $this->DB->Query(
"SELECT * FROM MetadataFields"
1323 .
" WHERE Owner IS NOT NULL AND LENGTH(Owner) > 0"
1324 .
" AND SchemaId = ".intval($this->
Id));
1326 while (FALSE !== ($Row = $this->DB->FetchRow()))
1328 $FieldId = $Row[
"FieldId"];
1329 $Fields[$FieldId] = $this->
GetField($FieldId);
1345 # fetch the IDs all of the metadata schemas
1346 $Database->Query(
"SELECT * FROM MetadataSchemas");
1347 $SchemaIds = $Database->FetchColumn(
"SchemaId");
1349 # construct objects from the IDs
1350 foreach ($SchemaIds as $SchemaId)
1365 if (is_callable($Callback))
1367 self::$OwnerListRetrievalFunction = $Callback;
1378 # if an owner list retrieval function and default schema exists
1379 if (self::$OwnerListRetrievalFunction
1380 && self::SchemaExistsWithId(self::SCHEMAID_DEFAULT))
1382 # retrieve the list of owners that currently exist
1383 $OwnerList = call_user_func(self::$OwnerListRetrievalFunction);
1385 # an array is expected
1386 if (is_array($OwnerList))
1390 # get each metadata field that is owned by a plugin
1391 $OwnedFields = $Schema->GetOwnedFields();
1393 # loop through each owned field
1394 foreach ($OwnedFields as $OwnedField)
1396 # the owner of the current field
1397 $Owner = $OwnedField->Owner();
1399 # if the owner of the field is in the list of owners that
1400 # currently exist, i.e., available plugins
1401 if (in_array($Owner, $OwnerList))
1403 # enable the field and reset its "enable on owner return"
1404 # flag if the "enable on owner return" flag is currently
1405 # set to true. in other words, re-enable the field since
1406 # the owner has returned to the list of existing owners
1407 if ($OwnedField->EnableOnOwnerReturn())
1409 $OwnedField->Enabled(TRUE);
1410 $OwnedField->EnableOnOwnerReturn(FALSE);
1414 # if the owner of the field is *not* in the list of owners
1415 # that currently exist, i.e., available plugins
1418 # first, see if the field is currently enabled since it
1419 # will determine whether the field is re-enabled when
1420 # the owner becomes available again
1421 $Enabled = $OwnedField->Enabled();
1423 # if the field is enabled, set its "enable on owner
1424 # return" flag to true and disable the field. nothing
1425 # needs to be done if the field is already disabled
1428 $OwnedField->EnableOnOwnerReturn($Enabled);
1429 $OwnedField->Enabled(FALSE);
1447 $this->FieldCompareDisplayOrder[$Field->Id()] = $Index++;
1454 $this->FieldCompareEditOrder[$Field->Id()] = $Index++;
1464 # try to fetch an existing display order
1467 self::ORDER_DISPLAY_NAME);
1469 # if the order doesn't exist
1470 if (is_null($DisplayOrder))
1472 $OldId = $GLOBALS[
"SysConfig"]->FieldDisplayFolder();
1474 # if the older version of MetadataFieldOrder was in use
1475 if ($OldId && $this->
Id() == self::SCHEMAID_DEFAULT)
1477 # add an entry for the existing folder
1479 INSERT INTO MetadataFieldOrders
1480 SET SchemaId = '".addslashes($this->
Id()).
"',
1481 OrderId = '".addslashes($OldId).
"',
1482 OrderName = '".addslashes(self::ORDER_DISPLAY_NAME).
"'");
1488 # otherwise, just create a new order
1493 self::ORDER_DISPLAY_NAME,
1494 self::GetOrderForUpgrade($this, self::ORDER_DISPLAY_NAME));
1498 return $DisplayOrder;
1507 # try to fetch an existing edit order
1510 self::ORDER_EDIT_NAME);
1512 # if the order doesn't exist
1513 if (is_null($EditOrder))
1515 $OldId = $GLOBALS[
"SysConfig"]->FieldEditFolder();
1517 # if the older version of MetadataFieldOrder was in use
1518 if ($OldId && $this->
Id() == self::SCHEMAID_DEFAULT)
1520 # add an entry for the existing folder
1522 INSERT INTO MetadataFieldOrders
1523 SET SchemaId = '".addslashes($this->
Id()).
"',
1524 OrderId = '".addslashes($OldId).
"',
1525 OrderName = '".addslashes(self::ORDER_EDIT_NAME).
"'");
1531 # otherwise, just create a new order
1536 self::ORDER_EDIT_NAME,
1537 self::GetOrderForUpgrade($this, self::ORDER_EDIT_NAME));
1564 return ($FieldA->GetDisplayName() < $FieldB->GetDisplayName()) ? -1 : 1;
1577 $PositionA = GetArrayValue($Order, $FieldA->Id(), 0);
1578 $PositionB = GetArrayValue($Order, $FieldB->Id(), 0);
1580 return $PositionA < $PositionB ? -1 : 1;
1593 # don't do an upgrade for non-default schemas
1594 if ($Schema->
Id() !== self::SCHEMAID_DEFAULT)
1599 # get the default display order
1600 if ($Name == self::ORDER_DISPLAY_NAME)
1602 # try to get the order from the database and, failing that, use the
1603 # defaults in the class
1604 $Rows = self::GetRowsForUpgrade(self::MDFORDER_DISPLAY);
1605 return count($Rows) ? $Rows: self::$DefaultDisplayOrder;
1608 # get the default edit order
1609 if ($Name == self::ORDER_EDIT_NAME)
1611 # try to get the order from the database and, failing that, use the
1612 # defaults in the class
1613 $Rows = self::GetRowsForUpgrade(self::MDFORDER_EDITING);
1614 return count($Rows) ? $Rows: self::$DefaultEditOrder;
1617 # otherwise make no assumptions about the order
1632 # temporarily suppress errors
1636 # see if the old columns exist
1637 $Handle = $Database->Query(
"
1638 SELECT EditingOrderPosition
1642 # the columns do not exist so an upgrade cannot be performed
1643 if ($Handle === FALSE)
1648 # determine which column to use for ordering
1650 ?
"DisplayOrderPosition" :
"EditingOrderPosition";
1652 # query for the fields in their proper order
1657 ORDER BY ".$Column.
" ASC");
1659 # restore the earlier error setting
1662 # return the resulting field IDs
1663 return $Database->FetchColumn(
"FieldId");
1808 # ---- PRIVATE INTERFACE -------------------------------------------------
1812 private $ResourceName;
1813 private $AuthoringPrivileges;
1814 private $EditingPrivileges;
1815 private $ViewingPrivileges;
1817 private $FieldCompareType;
1819 private $NewFields = array();
1820 private $ErrorMsgs = array();
1821 private static $FieldMappings;
1841 private function ConvertXmlToPrivilegeSet($Xml)
1843 # clear any existing errors
1844 if (array_key_exists(__METHOD__, $this->ErrorMsgs))
1845 { unset($this->ErrorMsgs[__METHOD__]); }
1847 # create new privilege set
1850 # for each XML child
1851 foreach ($Xml as $Tag => $Value)
1853 # take action based on element name
1856 case "PrivilegeSet":
1857 # convert child data to new set
1858 $NewSet = $this->ConvertXmlToPrivilegeSet($Value);
1860 # add new set to our privilege set
1861 $PrivSet->AddSet($NewSet);
1864 case "AddCondition":
1865 # start with default values for optional parameters
1866 unset($ConditionField);
1867 $ConditionValue = NULL;
1868 $ConditionOperator =
"==";
1870 # pull out parameters
1871 foreach ($Value as $ParamName => $ParamValue)
1873 $ParamValue = trim($ParamValue);
1878 (
string)$ParamValue, TRUE);
1879 if ($ConditionField === NULL)
1881 # record error about unknown field
1882 $this->ErrorMsgs[__METHOD__][] =
1883 "Unknown metadata field name found"
1884 .
" in AddCondition (".$ParamValue.
").";
1892 $ConditionValue = ($ParamValue ==
"NULL")
1893 ? NULL : (
string)$ParamValue;
1897 $ConditionOperator = (string)$ParamValue;
1901 # record error about unknown parameter name
1902 $this->ErrorMsgs[__METHOD__][] =
1903 "Unknown tag found in AddCondition ("
1913 if (!isset($ConditionField))
1915 # record error about no field value
1916 $this->ErrorMsgs[__METHOD__][] =
1917 "No metadata field specified in AddCondition.";
1923 # add conditional to privilege set
1924 $PrivSet->AddCondition($ConditionField,
1925 $ConditionValue, $ConditionOperator);
1929 # strip any excess whitespace off of value
1930 $Value = trim($Value);
1932 # if child looks like valid method name
1933 if (method_exists(
"PrivilegeSet", $Tag))
1935 # convert constants if needed
1936 if (defined($Value)) { $Value = constant($Value); }
1938 # convert booleans if needed
1939 if (strtoupper($Value) ==
"TRUE") { $Value = TRUE; }
1940 elseif (strtoupper($Value) ==
"FALSE") { $Value = FALSE; }
1942 # set value using child data
1943 $PrivSet->$Tag((
string)$Value);
1947 # record error about bad tag
1948 $this->ErrorMsgs[__METHOD__][] =
1949 "Unknown tag encountered (".$Tag.
").";
1958 # 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.