CWIS Developer Documentation
MetadataSchema.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: MetadataSchema.php
4 #
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
8 #
9 
13 class MetadataSchema extends ItemFactory {
14 
15  # ---- PUBLIC INTERFACE --------------------------------------------------
16 
17  # metadata field base types
18  # (must parallel MetadataFields.FieldType declaration in install/CreateTables.sql
19  # and MetadataField::$FieldTypeDBEnums declaration below)
20  const MDFTYPE_TEXT = 1;
21  const MDFTYPE_PARAGRAPH = 2;
22  const MDFTYPE_NUMBER = 4;
23  const MDFTYPE_DATE = 8;
24  const MDFTYPE_TIMESTAMP = 16;
25  const MDFTYPE_FLAG = 32;
26  const MDFTYPE_TREE = 64;
28  const MDFTYPE_OPTION = 256;
29  const MDFTYPE_USER = 512;
30  const MDFTYPE_IMAGE = 1024;
31  const MDFTYPE_FILE = 2048;
32  const MDFTYPE_URL = 4096;
33  const MDFTYPE_POINT = 8192;
34  const MDFTYPE_REFERENCE = 16384;
35 
36  # types of field ordering
37  const MDFORDER_DISPLAY = 1;
38  const MDFORDER_EDITING = 2;
40 
41  # error status codes
42  const MDFSTAT_OK = 1;
43  const MDFSTAT_ERROR = 2;
47  const MDFSTAT_ILLEGALNAME = 32;
49  const MDFSTAT_ILLEGALLABEL = 128;
50 
51  # special schema IDs
52  const SCHEMAID_DEFAULT = 0;
53  const SCHEMAID_USER = 1;
54 
55  # resource names
56  const RESOURCENAME_DEFAULT = "Resource";
57  const RESOURCENAME_USER = "User";
58 
59  # names used for display and edit orders
60  const ORDER_DISPLAY_NAME = "Display";
61  const ORDER_EDIT_NAME = "Edit";
62 
71  function MetadataSchema($SchemaId = self::SCHEMAID_DEFAULT)
72  {
73  # set schema ID
74  $this->Id = $SchemaId;
75 
76  # set up item factory base class
77  $this->ItemFactory(
78  "MetadataField", "MetadataFields", "FieldId", "FieldName", FALSE,
79  "SchemaId = ".intval($this->Id()));
80 
81  # load schema info from database
82  $this->DB->Query("SELECT * FROM MetadataSchemas"
83  ." WHERE SchemaId = ".intval($SchemaId));
84  if ($this->DB->NumRowsSelected() < 1)
85  {
86  throw new Exception("Attempt to load metadata schema with "
87  ." invalid ID (".$SchemaId.").");
88  }
89  $Info = $this->DB->FetchRow();
90  $this->Name = $Info["Name"];
91  $this->AuthoringPrivileges = new PrivilegeSet($Info["AuthoringPrivileges"]);
92  $this->EditingPrivileges = new PrivilegeSet($Info["EditingPrivileges"]);
93  $this->ViewingPrivileges = new PrivilegeSet($Info["ViewingPrivileges"]);
94  $this->ViewPage = $Info["ViewPage"];
95 
96  # start with field info caching enabled
97  $this->CachingOn = TRUE;
98  }
99 
114  static function Create($Name,
115  PrivilegeSet $AuthorPrivs = NULL,
116  PrivilegeSet $EditPrivs = NULL,
117  PrivilegeSet $ViewPrivs = NULL,
118  $ViewPage = "",
119  $ResourceName = NULL)
120  {
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(); }
125 
126  # add schema to database
127  $DB = new Database;
128  if (strtoupper($Name) == "DEFAULT")
129  {
130  $Id = self::SCHEMAID_DEFAULT;
131  }
132  elseif (strtoupper($Name) == "USER")
133  {
134  $Id = self::SCHEMAID_USER;
135  }
136  else
137  {
138  $Id = $DB->Query("SELECT SchemaId FROM MetadataSchemas"
139  ." ORDER BY SchemaId DESC LIMIT 1", "SchemaId") + 1;
140  }
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())."')");
150 
151  # construct the new schema
152  $Schema = new MetadataSchema($Id);
153 
154  # set schema name if none supplied
155  if (!strlen($Name))
156  {
157  $Schema->Name("Metadata Schema ".$Id);
158  }
159 
160  # set the resource name if one is supplied
161  if (!is_null($ResourceName))
162  {
163  $Schema->ResourceName($ResourceName);
164  }
165 
166  # return the new schema
167  return $Schema;
168  }
169 
175  static function SchemaExistsWithId($SchemaId)
176  {
177  $DB = new Database();
178  $DB->Query("SELECT * FROM MetadataSchemas"
179  ." WHERE SchemaId = ".intval($SchemaId));
180  return ($DB->NumRowsSelected() > 0) ? TRUE : FALSE;
181  }
182 
188  function Id()
189  {
190  # return value to caller
191  return $this->Id;
192  }
193 
199  function Name($NewValue = NULL)
200  {
201  # set new name if one supplied
202  if ($NewValue !== NULL)
203  {
204  $this->DB->Query("UPDATE MetadataSchemas"
205  ." SET Name = '".addslashes($NewValue)."'"
206  ." WHERE SchemaId = '".intval($this->Id)."'");
207  $this->Name = $NewValue;
208  }
209 
210  # get the name if it hasn't been cached yet
211  if (!isset($this->Name))
212  {
213  $this->Name = $this->DB->Query("SELECT * FROM MetadataSchemas"
214  ." WHERE SchemaId = '".intval($this->Id)."'", "Name");
215  }
216 
217  # return current value to caller
218  return $this->Name;
219  }
220 
226  function ResourceName($NewValue = NULL)
227  {
228  # set new resource name if one supplied
229  if ($NewValue !== NULL)
230  {
231  $this->DB->Query("
232  UPDATE MetadataSchemas
233  SET ResourceName = '".addslashes($NewValue)."'
234  WHERE SchemaId = '".intval($this->Id)."'");
235  $this->ResourceName = $NewValue;
236  }
237 
238  # get the name if it hasn't been cached yet
239  if (!isset($this->ResourceName))
240  {
241  $this->ResourceName = $this->DB->Query("
242  SELECT * FROM MetadataSchemas
243  WHERE SchemaId = '".intval($this->Id)."'",
244  "ResourceName");
245 
246  # use the default resource name if one isn't set
247  if (!strlen(trim($this->ResourceName)))
248  {
249  $this->ResourceName = self::RESOURCENAME_DEFAULT;
250  }
251  }
252 
253  # return current value to caller
254  return $this->ResourceName;
255  }
256 
262  function ViewPage($NewValue = NULL)
263  {
264  # set new viewing page if one supplied
265  if ($NewValue !== NULL)
266  {
267  $this->DB->Query("UPDATE MetadataSchemas"
268  ." SET ViewPage = '".addslashes($NewValue)."'"
269  ." WHERE SchemaId = '".intval($this->Id)."'");
270  $this->ViewPage = $NewValue;
271  }
272 
273  # get the view page if it hasn't been cached yet
274  if (!isset($this->ViewPage))
275  {
276  $this->ViewPage = $this->DB->Query("SELECT * FROM MetadataSchemas"
277  ." WHERE SchemaId = '".intval($this->Id)."'", "ViewPage");
278  }
279 
280  # return current value to caller
281  return $this->ViewPage;
282  }
283 
289  function AuthoringPrivileges(PrivilegeSet $NewValue = NULL)
290  {
291  # if new privileges supplied
292  if ($NewValue !== NULL)
293  {
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));
299  $this->AuthoringPrivileges = $NewValue;
300  }
301 
302  # return current value to caller
303  return $this->AuthoringPrivileges;
304  }
305 
311  function EditingPrivileges(PrivilegeSet $NewValue = NULL)
312  {
313  # if new privileges supplied
314  if ($NewValue !== NULL)
315  {
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));
321  $this->EditingPrivileges = $NewValue;
322  }
323 
324  # return current value to caller
325  return $this->EditingPrivileges;
326  }
327 
333  function ViewingPrivileges(PrivilegeSet $NewValue = NULL)
334  {
335  # if new privileges supplied
336  if ($NewValue !== NULL)
337  {
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));
343  $this->ViewingPrivileges = $NewValue;
344  }
345 
346  # return current value to caller
347  return $this->ViewingPrivileges;
348  }
349 
357  function UserCanAuthor($User)
358  {
359  # get authoring privilege set for schema
360  $AuthorPrivs = $this->AuthoringPrivileges();
361 
362  # get privilege set for user
363  $UserPrivs = $User->Privileges();
364 
365  # user can author if privileges are greater than resource set
366  $CanAuthor = $UserPrivs->IsGreaterThan($AuthorPrivs);
367 
368  # allow plugins to modify result of permission check
369  $SignalResult = $GLOBALS["AF"]->SignalEvent(
370  "EVENT_RESOURCE_AUTHOR_PERMISSION_CHECK", array(
371  "Schema" => $this,
372  "User" => $User,
373  "CanAuthor" => $CanAuthor));
374  $CanAuthor = $SignalResult["CanAuthor"];
375 
376  # report back to caller whether user can author field
377  return $CanAuthor;
378  }
379 
386  {
387  # get the query/GET parameters for the view page
388  $Query = parse_url($this->ViewPage(), PHP_URL_QUERY);
389 
390  # the URL couldn't be parsed
391  if (!is_string($Query))
392  {
393  return NULL;
394  }
395 
396  # parse the GET parameters out of the query string
397  $GetVars = ParseQueryString($Query);
398 
399  # search for the ID parameter
400  $Result = array_search("\$ID", $GetVars);
401 
402  return $Result !== FALSE ? $Result : NULL;
403  }
404 
417  function PathMatchesViewPage($Path)
418  {
419  # get the query/GET parameters for the view page
420  $Query = parse_url($this->ViewPage(), PHP_URL_QUERY);
421 
422  # can't perform matching if the URL couldn't be parsed
423  if (!is_string($Query))
424  {
425  return FALSE;
426  }
427 
428  # parse the GET parameters out of the query string
429  $GetVars = ParseQueryString($Query);
430 
431  # now, get the query/GET parameters from the path given
432  $PathQuery = parse_url($Path, PHP_URL_QUERY);
433 
434  # can't perform matching if the URL couldn't be parsed
435  if (!is_string($PathQuery))
436  {
437  return FALSE;
438  }
439 
440  # parse the GET parameters out of the path's query string
441  $PathGetVars = ParseQueryString($PathQuery);
442 
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)
447  {
448  # there's a required parameter that is not included in the path GET
449  # parameters
450  if (!array_key_exists($GetVarName, $PathGetVars))
451  {
452  return FALSE;
453  }
454 
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} != "$"))
459  {
460  return FALSE;
461  }
462  }
463 
464  # the path matches the view page path
465  return TRUE;
466  }
467 
472  function CacheData($NewValue)
473  {
474  $this->CachingOn = $NewValue;
475  }
476 
486  function AddField($FieldName, $FieldType, $Optional = TRUE, $DefaultValue = NULL)
487  {
488  # clear any existing error messages
489  if (array_key_exists(__METHOD__, $this->ErrorMsgs))
490  { unset($this->ErrorMsgs[__METHOD__]); }
491 
492  # create new field
493  try
494  {
495  $Field = MetadataField::Create($this->Id(), $FieldType,
496  $FieldName, $Optional, $DefaultValue);
497  }
498  catch (Exception $Exception)
499  {
500  $this->ErrorMsgs[__METHOD__][] = $Exception->getMessage();
501  $Field = NULL;
502  }
503 
504  # return new field to caller
505  return $Field;
506  }
507 
520  function AddFieldsFromXmlFile($FileName, $TestRun = FALSE)
521  {
522  # clear loading status
523  $this->NewFields = array();
524  if (array_key_exists(__METHOD__, $this->ErrorMsgs))
525  { unset($this->ErrorMsgs[__METHOD__]); }
526 
527  # check that file exists and is readable
528  if (!file_exists($FileName))
529  {
530  $this->ErrorMsgs[__METHOD__][] = "Could not find XML file '"
531  .$FileName."'.";
532  return FALSE;
533  }
534  elseif (!is_readable($FileName))
535  {
536  $this->ErrorMsgs[__METHOD__][] = "Could not read from XML file '"
537  .$FileName."'.";
538  return FALSE;
539  }
540 
541  # load XML from file
542  libxml_use_internal_errors(TRUE);
543  $XmlData = simplexml_load_file($FileName);
544  $Errors = libxml_get_errors();
545  libxml_use_internal_errors(FALSE);
546 
547  # if XML load failed
548  if ($XmlData === FALSE)
549  {
550  # retrieve XML error messages
551  foreach ($Errors as $Err)
552  {
553  $ErrType = ($Err->level == LIBXML_ERR_WARNING) ? "Warning"
554  : (($Err->level == LIBXML_ERR_WARNING) ? "Error"
555  : "Fatal Error");
556  $this->ErrorMsgs[__METHOD__][] = "XML ".$ErrType.": ".$Err->message
557  ." (".$Err->file.":".$Err->line.",".$Err->column.")";
558  }
559  }
560  # else if no metadata fields found record error message
561  elseif (!count($XmlData->MetadataField))
562  {
563  $this->ErrorMsgs[__METHOD__][] = "No metadata fields found.";
564  }
565  # else process metadata fields
566  else
567  {
568  # for each metadata field entry found
569  $FieldsAdded = 0;
570  $FieldIndex = 0;
571  foreach ($XmlData->MetadataField as $FieldXml)
572  {
573  $FieldIndex++;
574 
575  # pull out field type if present
576  if (isset($FieldXml->Type))
577  {
578  $FieldType = "MetadataSchema::".$FieldXml->Type;
579  if (!defined($FieldType))
580  {
581  $FieldType = "MetadataSchema::MDFTYPE_"
582  .strtoupper(preg_replace("/\\s+/", "",
583  $FieldXml->Type));
584  }
585  }
586 
587  # if required values are missing
588  if (!isset($FieldXml->Name) || !isset($FieldXml->Type)
589  || !defined($FieldType))
590  {
591  # add error message about required value missing
592  if (!isset($FieldXml->Name))
593  {
594  $this->ErrorMsgs[__METHOD__][] =
595  "Field name not found (MetadataField #"
596  .$FieldIndex.").";
597  }
598  else
599  {
600  $this->ErrorMsgs[__METHOD__][] =
601  "Valid type not found for field '"
602  .$FieldXml->Name."' (MetadataField #"
603  .$FieldIndex.").";
604  }
605  }
606  # else if there is not already a field with this name
607  elseif (!$this->NameIsInUse(trim($FieldXml->Name)))
608  {
609  # create new field
610  $Field = $this->AddField($FieldXml->Name, constant($FieldType));
611 
612  # if field creation failed
613  if ($Field === NULL)
614  {
615  # add any error message to our error list
616  $ErrorMsgs = $this->ErrorMessages("AddField");
617  foreach ($ErrorMsgs as $Msg)
618  {
619  $this->ErrorMsgs[__METHOD__][] =
620  $Msg." (AddField)";
621  }
622  }
623  else
624  {
625  # add field to list of created fields
626  $this->NewFields[$Field->Id()] = $Field;
627 
628  # for other field attributes
629  foreach ($FieldXml as $MethodName => $Value)
630  {
631  # if tags look valid and have not already been set
632  if (method_exists($Field, $MethodName)
633  && ($MethodName != "Name")
634  && ($MethodName != "Type"))
635  {
636  # if tag indicates privilege set
637  if (preg_match("/^[a-z]+Privileges\$/i",
638  $MethodName))
639  {
640  # save element for later processing
641  $PrivilegesToSet[$Field->Id()][$MethodName] = $Value;
642  }
643  else
644  {
645  # condense down any extraneous whitespace
646  $Value = preg_replace("/\s+/", " ", trim($Value));
647 
648  # set value for field
649  $Field->$MethodName($Value);
650  }
651  }
652  }
653 
654  # save the temp ID so that any privileges to set can be
655  # mapped to the actual ID when the field is made
656  # permanent
657  $TempId = $Field->Id();
658 
659  # make new field permanent
660  $Field->IsTempItem(FALSE);
661 
662  # map privileges to set to the permanent field ID
663  if (isset($PrivilegesToSet))
664  {
665  # copy the privileges over
666  $PrivilegesToSet[$Field->Id()] =
667  $PrivilegesToSet[$TempId];
668 
669  # remove the values for the temp ID
670  unset($PrivilegesToSet[$TempId]);
671  }
672  }
673  }
674  }
675 
676  # if we have privileges to set
677  if (isset($PrivilegesToSet))
678  {
679  # for each field with privileges
680  foreach ($PrivilegesToSet as $FieldId => $Privileges)
681  {
682  # load the field for which to set the privileges
683  $Field = new MetadataField($FieldId);
684 
685  # for each set of privileges for field
686  foreach ($Privileges as $MethodName => $Value)
687  {
688  # convert privilege value
689  $Value = $this->ConvertXmlToPrivilegeSet($Value);
690 
691  # if conversion failed
692  if ($Value === NULL)
693  {
694  # add resulting error messages to our list
695  $ErrorMsgs = $this->ErrorMessages(
696  "ConvertXmlToPrivilegeSet");
697  foreach ($ErrorMsgs as $Msg)
698  {
699  $this->ErrorMsgs[__METHOD__][] =
700  $Msg." (ConvertXmlToPrivilegeSet)";
701  }
702  }
703  else
704  {
705  # set value for field
706  $Field->$MethodName($Value);
707  }
708  }
709  }
710  }
711 
712  # if errors were found during creation
713  if (array_key_exists(__METHOD__, $this->ErrorMsgs) || $TestRun)
714  {
715  # remove any fields that were created
716  foreach ($this->NewFields as $Field)
717  {
718  $Field->Drop();
719  }
720  $this->NewFields = array();
721  }
722  }
723 
724  # report success or failure based on whether errors were recorded
725  return (array_key_exists(__METHOD__, $this->ErrorMsgs)) ? FALSE : TRUE;
726  }
727 
733  function NewFields()
734  {
735  return $this->NewFields;
736  }
737 
747  function ErrorMessages($Method = NULL)
748  {
749  if ($Method === NULL)
750  {
751  return $this->ErrorMsgs;
752  }
753  else
754  {
755  if (!method_exists($this, $Method))
756  {
757  throw new Exception("Error messages requested for non-existent"
758  ." method (".$Method.").");
759  }
760  return array_key_exists(__CLASS__."::".$Method, $this->ErrorMsgs)
761  ? $this->ErrorMsgs[__CLASS__."::".$Method] : array();
762  }
763  }
764 
774  function AddFieldFromXml($Xml)
775  {
776  # assume field addition will fail
777  $Field = self::MDFSTAT_ERROR;
778 
779  # add XML prefixes if needed
780  $Xml = trim($Xml);
781  if (!preg_match("/^<\?xml/i", $Xml))
782  {
783  if (!preg_match("/^<document>/i", $Xml))
784  {
785  $Xml = "<document>".$Xml."</document>";
786  }
787  $Xml = "<?xml version='1.0'?".">".$Xml;
788  }
789 
790  # parse XML
791  $XmlData = simplexml_load_string($Xml);
792 
793  # if required values are present
794  if (is_object($XmlData)
795  && isset($XmlData->Name)
796  && isset($XmlData->Type)
797  && constant("MetadataSchema::".$XmlData->Type))
798  {
799  # create the metadata field
800  $Field = $this->AddField(
801  $XmlData->Name,
802  constant("MetadataSchema::".$XmlData->Type));
803 
804  # if field creation succeeded
805  if ($Field != NULL)
806  {
807  # for other field attributes
808  foreach ($XmlData as $MethodName => $Value)
809  {
810  # if they look valid and have not already been set
811  if (method_exists($Field, $MethodName)
812  && ($MethodName != "Name")
813  && ($MethodName != "Type"))
814  {
815  # if tag indicates privilege set
816  if (preg_match("/^[a-z]+Privileges\$/i",
817  $MethodName))
818  {
819  # save element for later processing
820  $PrivilegesToSet[$MethodName] = $Value;
821  }
822  else
823  {
824  # condense down any extraneous whitespace
825  $Value = preg_replace("/\s+/", " ", trim($Value));
826 
827  # set value for field
828  $Field->$MethodName($Value);
829  }
830  }
831  }
832 
833  # make new field permanent
834  $Field->IsTempItem(FALSE);
835 
836  # if we have privileges to set
837  if (isset($PrivilegesToSet))
838  {
839  # for each set of privileges for field
840  foreach ($PrivilegesToSet as $MethodName => $Value)
841  {
842  # convert privilege value
843  $Value = $this->ConvertXmlToPrivilegeSet($Value);
844 
845  # if conversion failed
846  if ($Value === NULL)
847  {
848  # add resulting error messages to our list
849  $ErrorMsgs = $this->ErrorMessages(
850  "ConvertXmlToPrivilegeSet");
851  foreach ($ErrorMsgs as $Msg)
852  {
853  $this->ErrorMsgs[__METHOD__][] =
854  $Msg." (ConvertXmlToPrivilegeSet)";
855  }
856  }
857  else
858  {
859  # set value for field
860  $Field->$MethodName($Value);
861  }
862  }
863  }
864  }
865  }
866 
867  # return new field (if any) to caller
868  return $Field;
869  }
870 
876  function DropField($FieldId)
877  {
878  $Field = $this->GetField($FieldId);
879  if ($Field !== NULL)
880  {
881  $Field->Drop();
882  return TRUE;
883  }
884  else
885  {
886  return FALSE;
887  }
888  }
889 
895  function GetField($FieldId)
896  {
897  static $Fields;
898 
899  # if caching is off or field is not already loaded
900  if (($this->CachingOn != TRUE) || !isset($Fields[$FieldId]))
901  {
902  # retrieve field
903  try
904  {
905  $Fields[$FieldId] = new MetadataField($FieldId);
906  }
907  catch (Exception $Exception)
908  {
909  $Fields[$FieldId] = NULL;
910  }
911  }
912 
913  # return field to caller
914  return $Fields[$FieldId];
915  }
916 
923  function GetFieldByName($FieldName, $IgnoreCase = FALSE)
924  {
925  $FieldId = $this->GetFieldIdByName($FieldName, $IgnoreCase);
926  return ($FieldId === NULL) ? NULL : $this->GetField($FieldId);
927  }
928 
935  function GetFieldByLabel($FieldLabel, $IgnoreCase = FALSE)
936  {
937  $FieldId = $this->GetFieldIdByLabel($FieldLabel, $IgnoreCase);
938  return ($FieldId === NULL) ? NULL : $this->GetField($FieldId);
939  }
940 
948  function GetFieldIdByName($FieldName, $IgnoreCase = FALSE)
949  {
950  static $FieldIdsByName;
951 
952  # if caching is off or field ID is already loaded
953  if (($this->CachingOn != TRUE) || !isset($FieldIdsByName[$this->Id][$FieldName]))
954  {
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");
962  }
963 
964  return $FieldIdsByName[$this->Id][$FieldName];
965  }
966 
974  function GetFieldIdByLabel($FieldLabel, $IgnoreCase = FALSE)
975  {
976  static $FieldIdsByLabel;
977 
978  # if caching is off or field ID is already loaded
979  if (($this->CachingOn != TRUE) || !isset($FieldIdsByLabel[$FieldLabel]))
980  {
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");
988  }
989 
990  return $FieldIdsByLabel[$FieldLabel];
991  }
992 
998  function FieldExists($FieldName) { return $this->NameIsInUse($FieldName); }
999 
1013  function GetFields($FieldTypes = NULL, $OrderType = NULL,
1014  $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
1015  {
1016  # create empty array to pass back
1017  $Fields = array();
1018 
1019  # for each field type in database
1020  if ($IncludeTempFields && $IncludeDisabledFields)
1021  {
1022  $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields"
1023  ." WHERE SchemaId = ".intval($this->Id));
1024  }
1025  else
1026  {
1027  if ($IncludeTempFields)
1028  {
1029  $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields"
1030  ." WHERE Enabled != 0"
1031  ." AND SchemaId = ".intval($this->Id));
1032  }
1033  elseif ($IncludeDisabledFields)
1034  {
1035  $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields"
1036  ." WHERE FieldId >= 0"
1037  ." AND SchemaId = ".intval($this->Id));
1038  }
1039  else
1040  {
1041  $this->DB->Query("SELECT FieldId, FieldType FROM MetadataFields"
1042  ." WHERE FieldId >= 0 AND Enabled != 0"
1043  ." AND SchemaId = ".intval($this->Id));
1044  }
1045  }
1046  while ($Record = $this->DB->FetchRow())
1047  {
1048  # if no specific type requested or if field is of requested type
1049  if (($FieldTypes == NULL)
1050  || (MetadataField::$FieldTypePHPEnums[$Record["FieldType"]] & $FieldTypes))
1051  {
1052  # create field object and add to array to be passed back
1053  $Fields[$Record["FieldId"]] = $this->GetField($Record["FieldId"]);
1054  }
1055  }
1056 
1057  # if field sorting requested
1058  if ($OrderType !== NULL)
1059  {
1060  # update field comparison ordering if not set yet
1061  if (!$this->FieldCompareOrdersSet())
1062  {
1063  $this->UpdateFieldCompareOrders();
1064  }
1065 
1066  $this->FieldCompareType = $OrderType;
1067 
1068  # sort field array by requested order type
1069  uasort($Fields, array($this, "CompareFieldOrder"));
1070  }
1071 
1072  # return array of field objects to caller
1073  return $Fields;
1074  }
1075 
1090  function GetFieldNames($FieldTypes = NULL, $OrderType = NULL,
1091  $IncludeDisabledFields = FALSE, $IncludeTempFields = FALSE)
1092  {
1093  $Fields = $this->GetFields($FieldTypes, $OrderType,
1094  $IncludeDisabledFields, $IncludeTempFields);
1095 
1096  $FieldNames = array();
1097  foreach($Fields as $Field)
1098  {
1099  $FieldNames[$Field->Id()] = $Field->Name();
1100  }
1101 
1102  return $FieldNames;
1103  }
1104 
1121  function GetFieldsAsOptionList($OptionListName, $FieldTypes = NULL,
1122  $SelectedFieldId = NULL, $IncludeNullOption = TRUE,
1123  $AddEntries = NULL, $AllowMultiple = FALSE)
1124  {
1125  # retrieve requested fields
1126  $FieldNames = $this->GetFieldNames($FieldTypes);
1127 
1128  # transform field names to labels
1129  foreach ($FieldNames as $FieldId => $FieldName)
1130  {
1131  $FieldNames[$FieldId] = $this->GetField($FieldId)->GetDisplayName();
1132  }
1133 
1134  # begin HTML option list
1135  $Html = "<select id=\"".$OptionListName."\" name=\"".$OptionListName."\"";
1136 
1137  # if multiple selections should be allowed
1138  if ($AllowMultiple)
1139  {
1140  $Html .= " multiple=\"multiple\"";
1141  }
1142 
1143  $Html .= ">\n";
1144 
1145  if ($IncludeNullOption)
1146  {
1147  $Html .= "<option value=\"\">--</option>\n";
1148  }
1149 
1150  # make checking for IDs simpler
1151  if (!is_array($SelectedFieldId))
1152  {
1153  $SelectedFieldId = array($SelectedFieldId);
1154  }
1155 
1156  # for each metadata field
1157  foreach ($FieldNames as $Id => $Name)
1158  {
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";
1163  }
1164 
1165  # if additional entries were requested
1166  if ($AddEntries)
1167  {
1168  foreach ($AddEntries as $Value => $Label)
1169  {
1170  $Html .= "<option value=\"".$Value."\"";
1171  if (in_array($Value,$SelectedFieldId)) { $Html .= " selected"; }
1172  $Html .= ">".htmlspecialchars($Label)."</option>\n";
1173  }
1174  }
1175 
1176  # end HTML option list
1177  $Html .= "</select>\n";
1178 
1179  # return constructed HTML to caller
1180  return $Html;
1181  }
1182 
1188  function GetFieldTypes()
1189  {
1191  }
1192 
1199  {
1201  }
1202 
1207  function RemoveQualifierAssociations($QualifierIdOrObject)
1208  {
1209  # sanitize qualifier ID or grab it from object
1210  $QualifierIdOrObject = is_object($QualifierIdOrObject)
1211  ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
1212 
1213  # delete intersection records from database
1214  $this->DB->Query("DELETE FROM FieldQualifierInts"
1215  ." WHERE QualifierId = ".$QualifierIdOrObject);
1216  }
1217 
1223  function QualifierIsInUse($QualifierIdOrObject)
1224  {
1225  # sanitize qualifier ID or grab it from object
1226  $QualifierIdOrObject = is_object($QualifierIdOrObject)
1227  ? $QualifierIdOrObject->Id() : intval($QualifierIdOrObject);
1228 
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,
1233  "RecordCount");
1234 
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,
1239  "RecordCount");
1240 
1241  # report whether qualifier is in use based on defaults and associations
1242  return (($DefaultCount + $AssociationCount) > 0) ? TRUE : FALSE;
1243  }
1244 
1249  function GetHighestFieldId() { return $this->GetHighestItemId(); }
1250 
1258  static function StdNameToFieldMapping($MappedName, $FieldId = NULL)
1259  {
1260  if ($FieldId !== NULL)
1261  {
1262  self::$FieldMappings[$MappedName] = $FieldId;
1263  }
1264  return isset(self::$FieldMappings[$MappedName])
1265  ? self::$FieldMappings[$MappedName] : NULL;
1266  }
1267 
1274  static function FieldToStdNameMapping($FieldId)
1275  {
1276  if ($FieldId != -1)
1277  {
1278  foreach (self::$FieldMappings as $MappedName => $MappedFieldId)
1279  {
1280  if ($MappedFieldId == $FieldId)
1281  {
1282  return $MappedName;
1283  }
1284  }
1285  }
1286  return NULL;
1287  }
1288 
1296  function GetFieldByMappedName($MappedName)
1297  {
1298  return (self::StdNameToFieldMapping($MappedName) == NULL) ? NULL
1299  : $this->GetField($this->StdNameToFieldMapping($MappedName));
1300  }
1301 
1309  function GetFieldIdByMappedName($MappedName)
1310  {
1311  return self::StdNameToFieldMapping($MappedName);
1312  }
1313 
1318  function GetOwnedFields()
1319  {
1320  $Fields = array();
1321 
1322  $this->DB->Query("SELECT * FROM MetadataFields"
1323  ." WHERE Owner IS NOT NULL AND LENGTH(Owner) > 0"
1324  ." AND SchemaId = ".intval($this->Id));
1325 
1326  while (FALSE !== ($Row = $this->DB->FetchRow()))
1327  {
1328  $FieldId = $Row["FieldId"];
1329  $Fields[$FieldId] = $this->GetField($FieldId);
1330  }
1331 
1332  return $Fields;
1333  }
1334 
1340  static function GetAllSchemas()
1341  {
1342  $Database = new Database();
1343  $Schemas = array();
1344 
1345  # fetch the IDs all of the metadata schemas
1346  $Database->Query("SELECT * FROM MetadataSchemas");
1347  $SchemaIds = $Database->FetchColumn("SchemaId");
1348 
1349  # construct objects from the IDs
1350  foreach ($SchemaIds as $SchemaId)
1351  {
1352  $Schemas[$SchemaId] = new MetadataSchema($SchemaId);
1353  }
1354 
1355  return $Schemas;
1356  }
1357 
1363  static function SetOwnerListRetrievalFunction($Callback)
1364  {
1365  if (is_callable($Callback))
1366  {
1367  self::$OwnerListRetrievalFunction = $Callback;
1368  }
1369  }
1370 
1376  static function NormalizeOwnedFields()
1377  {
1378  # if an owner list retrieval function and default schema exists
1379  if (self::$OwnerListRetrievalFunction
1380  && self::SchemaExistsWithId(self::SCHEMAID_DEFAULT))
1381  {
1382  # retrieve the list of owners that currently exist
1383  $OwnerList = call_user_func(self::$OwnerListRetrievalFunction);
1384 
1385  # an array is expected
1386  if (is_array($OwnerList))
1387  {
1388  $Schema = new MetadataSchema(self::SCHEMAID_DEFAULT);
1389 
1390  # get each metadata field that is owned by a plugin
1391  $OwnedFields = $Schema->GetOwnedFields();
1392 
1393  # loop through each owned field
1394  foreach ($OwnedFields as $OwnedField)
1395  {
1396  # the owner of the current field
1397  $Owner = $OwnedField->Owner();
1398 
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))
1402  {
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())
1408  {
1409  $OwnedField->Enabled(TRUE);
1410  $OwnedField->EnableOnOwnerReturn(FALSE);
1411  }
1412  }
1413 
1414  # if the owner of the field is *not* in the list of owners
1415  # that currently exist, i.e., available plugins
1416  else
1417  {
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();
1422 
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
1426  if ($Enabled)
1427  {
1428  $OwnedField->EnableOnOwnerReturn($Enabled);
1429  $OwnedField->Enabled(FALSE);
1430  }
1431  }
1432  }
1433  }
1434  }
1435  }
1436 
1441  protected function UpdateFieldCompareOrders()
1442  {
1443  $Index = 0;
1444 
1445  foreach ($this->GetDisplayOrder()->GetFields() as $Field)
1446  {
1447  $this->FieldCompareDisplayOrder[$Field->Id()] = $Index++;
1448  }
1449 
1450  $Index = 0;
1451 
1452  foreach ($this->GetEditOrder()->GetFields() as $Field)
1453  {
1454  $this->FieldCompareEditOrder[$Field->Id()] = $Index++;
1455  }
1456  }
1457 
1462  public function GetDisplayOrder()
1463  {
1464  # try to fetch an existing display order
1465  $DisplayOrder = MetadataFieldOrder::GetOrderForSchema(
1466  $this,
1467  self::ORDER_DISPLAY_NAME);
1468 
1469  # if the order doesn't exist
1470  if (is_null($DisplayOrder))
1471  {
1472  $OldId = $GLOBALS["SysConfig"]->FieldDisplayFolder();
1473 
1474  # if the older version of MetadataFieldOrder was in use
1475  if ($OldId && $this->Id() == self::SCHEMAID_DEFAULT)
1476  {
1477  # add an entry for the existing folder
1478  $this->DB->Query("
1479  INSERT INTO MetadataFieldOrders
1480  SET SchemaId = '".addslashes($this->Id())."',
1481  OrderId = '".addslashes($OldId)."',
1482  OrderName = '".addslashes(self::ORDER_DISPLAY_NAME)."'");
1483 
1484  # use that folder
1485  $DisplayOrder = new MetadataFieldOrder($OldId);
1486  }
1487 
1488  # otherwise, just create a new order
1489  else
1490  {
1491  $DisplayOrder = MetadataFieldOrder::Create(
1492  $this,
1493  self::ORDER_DISPLAY_NAME,
1494  self::GetOrderForUpgrade($this, self::ORDER_DISPLAY_NAME));
1495  }
1496  }
1497 
1498  return $DisplayOrder;
1499  }
1500 
1505  public function GetEditOrder()
1506  {
1507  # try to fetch an existing edit order
1509  $this,
1510  self::ORDER_EDIT_NAME);
1511 
1512  # if the order doesn't exist
1513  if (is_null($EditOrder))
1514  {
1515  $OldId = $GLOBALS["SysConfig"]->FieldEditFolder();
1516 
1517  # if the older version of MetadataFieldOrder was in use
1518  if ($OldId && $this->Id() == self::SCHEMAID_DEFAULT)
1519  {
1520  # add an entry for the existing folder
1521  $this->DB->Query("
1522  INSERT INTO MetadataFieldOrders
1523  SET SchemaId = '".addslashes($this->Id())."',
1524  OrderId = '".addslashes($OldId)."',
1525  OrderName = '".addslashes(self::ORDER_EDIT_NAME)."'");
1526 
1527  # use that folder
1528  $EditOrder = new MetadataFieldOrder($OldId);
1529  }
1530 
1531  # otherwise, just create a new order
1532  else
1533  {
1534  $EditOrder = MetadataFieldOrder::Create(
1535  $this,
1536  self::ORDER_EDIT_NAME,
1537  self::GetOrderForUpgrade($this, self::ORDER_EDIT_NAME));
1538  }
1539  }
1540 
1541  return $EditOrder;
1542  }
1543 
1548  protected function FieldCompareOrdersSet()
1549  {
1550  return $this->FieldCompareDisplayOrder && $this->FieldCompareEditOrder;
1551  }
1552 
1560  protected function CompareFieldOrder($FieldA, $FieldB)
1561  {
1562  if ($this->FieldCompareType == MetadataSchema::MDFORDER_ALPHABETICAL)
1563  {
1564  return ($FieldA->GetDisplayName() < $FieldB->GetDisplayName()) ? -1 : 1;
1565  }
1566 
1567  if ($this->FieldCompareType == MetadataSchema::MDFORDER_EDITING)
1568  {
1570  }
1571 
1572  else
1573  {
1575  }
1576 
1577  $PositionA = GetArrayValue($Order, $FieldA->Id(), 0);
1578  $PositionB = GetArrayValue($Order, $FieldB->Id(), 0);
1579 
1580  return $PositionA < $PositionB ? -1 : 1;
1581  }
1582 
1591  protected static function GetOrderForUpgrade(MetadataSchema $Schema, $Name)
1592  {
1593  # don't do an upgrade for non-default schemas
1594  if ($Schema->Id() !== self::SCHEMAID_DEFAULT)
1595  {
1596  return array();
1597  }
1598 
1599  # get the default display order
1600  if ($Name == self::ORDER_DISPLAY_NAME)
1601  {
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;
1606  }
1607 
1608  # get the default edit order
1609  if ($Name == self::ORDER_EDIT_NAME)
1610  {
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;
1615  }
1616 
1617  # otherwise make no assumptions about the order
1618  return array();
1619  }
1620 
1628  protected static function GetRowsForUpgrade($Type)
1629  {
1630  $Database = new Database();
1631 
1632  # temporarily suppress errors
1633  $Setting = Database::DisplayQueryErrors();
1635 
1636  # see if the old columns exist
1637  $Handle = $Database->Query("
1638  SELECT EditingOrderPosition
1639  FROM MetadataFields
1640  LIMIT 1");
1641 
1642  # the columns do not exist so an upgrade cannot be performed
1643  if ($Handle === FALSE)
1644  {
1645  return array();
1646  }
1647 
1648  # determine which column to use for ordering
1649  $Column = $Type == MetadataSchema::MDFORDER_EDITING
1650  ? "DisplayOrderPosition" : "EditingOrderPosition";
1651 
1652  # query for the fields in their proper order
1653  $Database->Query("
1654  SELECT FieldId
1655  FROM MetadataFields
1656  WHERE FieldId > 0
1657  ORDER BY ".$Column." ASC");
1658 
1659  # restore the earlier error setting
1660  Database::DisplayQueryErrors($Setting);
1661 
1662  # return the resulting field IDs
1663  return $Database->FetchColumn("FieldId");
1664  }
1665 
1670  protected static $DefaultDisplayOrder = array(
1671  0 => 42,
1672  1 => 41,
1673  2 => 43,
1674  3 => 44,
1675  4 => 46,
1676  5 => 45,
1677  6 => 40,
1678  7 => 39,
1679  8 => 34,
1680  9 => 33,
1681  10 => 37,
1682  11 => 36,
1683  12 => 38,
1684  13 => 35,
1685  14 => 47,
1686  15 => 48,
1687  16 => 57,
1688  17 => 56,
1689  18 => 58,
1690  19 => 59,
1691  20 => 61,
1692  21 => 60,
1693  22 => 55,
1694  23 => 54,
1695  24 => 50,
1696  25 => 49,
1697  26 => 51,
1698  27 => 52,
1699  28 => 53,
1700  29 => 32,
1701  30 => 31,
1702  31 => 1,
1703  32 => 2,
1704  33 => 4,
1705  34 => 20,
1706  35 => 21,
1707  36 => 19,
1708  37 => 3,
1709  38 => 27,
1710  39 => 11,
1711  41 => 23,
1712  42 => 26,
1713  43 => 25,
1714  44 => 24,
1715  45 => 9,
1716  46 => 8,
1717  47 => 7,
1718  48 => 6,
1719  49 => 22,
1720  50 => 10,
1721  51 => 28,
1722  52 => 5,
1723  53 => 12,
1724  54 => 62,
1725  55 => 13,
1726  56 => 14,
1727  57 => 16,
1728  58 => 17,
1729  59 => 30,
1730  60 => 29,
1731  61 => 18,
1732  62 => 63,
1733  63 => 64,
1734  64 => 65,
1735  65 => 66);
1736 
1741  protected static $DefaultEditOrder = array(
1742  0 => 42,
1743  1 => 41,
1744  2 => 43,
1745  3 => 44,
1746  4 => 46,
1747  5 => 45,
1748  6 => 40,
1749  7 => 39,
1750  8 => 34,
1751  9 => 33,
1752  10 => 37,
1753  11 => 36,
1754  12 => 38,
1755  13 => 35,
1756  14 => 47,
1757  15 => 48,
1758  16 => 57,
1759  17 => 56,
1760  18 => 58,
1761  19 => 59,
1762  20 => 61,
1763  21 => 60,
1764  22 => 55,
1765  23 => 54,
1766  24 => 50,
1767  25 => 49,
1768  26 => 51,
1769  27 => 52,
1770  28 => 53,
1771  29 => 32,
1772  30 => 31,
1773  31 => 1,
1774  32 => 2,
1775  33 => 4,
1776  34 => 20,
1777  36 => 21,
1778  37 => 19,
1779  38 => 3,
1780  39 => 27,
1781  40 => 11,
1782  41 => 23,
1783  42 => 26,
1784  43 => 25,
1785  44 => 24,
1786  45 => 9,
1787  46 => 8,
1788  47 => 30,
1789  48 => 7,
1790  49 => 6,
1791  50 => 29,
1792  51 => 22,
1793  52 => 10,
1794  53 => 28,
1795  54 => 5,
1796  55 => 12,
1797  56 => 62,
1798  57 => 13,
1799  58 => 18,
1800  59 => 14,
1801  60 => 16,
1802  61 => 17,
1803  62 => 63,
1804  63 => 64,
1805  64 => 65,
1806  65 => 66);
1807 
1808  # ---- PRIVATE INTERFACE -------------------------------------------------
1809 
1810  private $Id;
1811  private $Name;
1812  private $ResourceName;
1813  private $AuthoringPrivileges;
1814  private $EditingPrivileges;
1815  private $ViewingPrivileges;
1816  private $ViewPage;
1817  private $FieldCompareType;
1818  private $CachingOn;
1819  private $NewFields = array();
1820  private $ErrorMsgs = array();
1821  private static $FieldMappings;
1823 
1827  protected $FieldCompareDisplayOrder = array();
1828 
1832  protected $FieldCompareEditOrder = array();
1833 
1841  private function ConvertXmlToPrivilegeSet($Xml)
1842  {
1843  # clear any existing errors
1844  if (array_key_exists(__METHOD__, $this->ErrorMsgs))
1845  { unset($this->ErrorMsgs[__METHOD__]); }
1846 
1847  # create new privilege set
1848  $PrivSet = new PrivilegeSet();
1849 
1850  # for each XML child
1851  foreach ($Xml as $Tag => $Value)
1852  {
1853  # take action based on element name
1854  switch ($Tag)
1855  {
1856  case "PrivilegeSet":
1857  # convert child data to new set
1858  $NewSet = $this->ConvertXmlToPrivilegeSet($Value);
1859 
1860  # add new set to our privilege set
1861  $PrivSet->AddSet($NewSet);
1862  break;
1863 
1864  case "AddCondition":
1865  # start with default values for optional parameters
1866  unset($ConditionField);
1867  $ConditionValue = NULL;
1868  $ConditionOperator = "==";
1869 
1870  # pull out parameters
1871  foreach ($Value as $ParamName => $ParamValue)
1872  {
1873  $ParamValue = trim($ParamValue);
1874  switch ($ParamName)
1875  {
1876  case "Field":
1877  $ConditionField = $this->GetFieldByName(
1878  (string)$ParamValue, TRUE);
1879  if ($ConditionField === NULL)
1880  {
1881  # record error about unknown field
1882  $this->ErrorMsgs[__METHOD__][] =
1883  "Unknown metadata field name found"
1884  ." in AddCondition (".$ParamValue.").";
1885 
1886  # bail out
1887  return NULL;
1888  }
1889  break;
1890 
1891  case "Value":
1892  $ConditionValue = ($ParamValue == "NULL")
1893  ? NULL : (string)$ParamValue;
1894  break;
1895 
1896  case "Operator":
1897  $ConditionOperator = (string)$ParamValue;
1898  break;
1899 
1900  default:
1901  # record error about unknown parameter name
1902  $this->ErrorMsgs[__METHOD__][] =
1903  "Unknown tag found in AddCondition ("
1904  .$ParamName.").";
1905 
1906  # bail out
1907  return NULL;
1908  break;
1909  }
1910  }
1911 
1912  # if no field value
1913  if (!isset($ConditionField))
1914  {
1915  # record error about no field value
1916  $this->ErrorMsgs[__METHOD__][] =
1917  "No metadata field specified in AddCondition.";
1918 
1919  # bail out
1920  return NULL;
1921  }
1922 
1923  # add conditional to privilege set
1924  $PrivSet->AddCondition($ConditionField,
1925  $ConditionValue, $ConditionOperator);
1926  break;
1927 
1928  default:
1929  # strip any excess whitespace off of value
1930  $Value = trim($Value);
1931 
1932  # if child looks like valid method name
1933  if (method_exists("PrivilegeSet", $Tag))
1934  {
1935  # convert constants if needed
1936  if (defined($Value)) { $Value = constant($Value); }
1937 
1938  # convert booleans if needed
1939  if (strtoupper($Value) == "TRUE") { $Value = TRUE; }
1940  elseif (strtoupper($Value) == "FALSE") { $Value = FALSE; }
1941 
1942  # set value using child data
1943  $PrivSet->$Tag((string)$Value);
1944  }
1945  else
1946  {
1947  # record error about bad tag
1948  $this->ErrorMsgs[__METHOD__][] =
1949  "Unknown tag encountered (".$Tag.").";
1950 
1951  # bail out
1952  return NULL;
1953  }
1954  break;
1955  }
1956  }
1957 
1958  # return new privilege set to caller
1959  return $PrivSet;
1960  }
1961 }
const MDFSTAT_ILLEGALLABEL
const ORDER_DISPLAY_NAME
GetHighestItemId($IgnoreSqlCondition=FALSE)
Retrieve highest item ID in use.
static $FieldTypeDBEnums
const RESOURCENAME_DEFAULT
static $FieldTypeDBAllowedEnums
GetFieldIdByName($FieldName, $IgnoreCase=FALSE)
Retrieve metadata field ID by name.
GetHighestFieldId()
Get highest field ID currently in use.
$FieldCompareEditOrder
The cache for metadata field edit ordering.
GetViewPageIdParameter()
Get the resource ID GET parameter for the view page for the schema.
GetAllowedFieldTypes()
Retrieve array of field types that user can create.
static GetOrderForUpgrade(MetadataSchema $Schema, $Name)
Get the metadata field order for the default metadata schema.
ViewingPrivileges(PrivilegeSet $NewValue=NULL)
Get/set privileges that allowing viewing resources with this schema.
Metadata schema (in effect a Factory class for MetadataField).
ErrorMessages($Method=NULL)
Get error messages (if any) from recent calls.
ResourceName($NewValue=NULL)
Get/set name of resources using this schema.
static $FieldTypePHPEnums
Class to build metadata field ordering functionality on top of the foldering functionality.
const MDFORDER_ALPHABETICAL
static Create($SchemaId, $FieldType, $FieldName, $Optional=NULL, $DefaultValue=NULL)
Create a new metadata field.
static NormalizeOwnedFields()
Disable owned fields that have an owner that is unavailable and re-enable fields if an owner has retu...
SQL database abstraction object with smart query caching.
UserCanAuthor($User)
Determine if the given user can author resources using this schema.
EditingPrivileges(PrivilegeSet $NewValue=NULL)
Get/set privileges that allowing editing resources with this schema.
GetFieldByName($FieldName, $IgnoreCase=FALSE)
Retrieve metadata field by name.
GetFieldIdByLabel($FieldLabel, $IgnoreCase=FALSE)
Retrieve metadata field ID by label.
GetFieldsAsOptionList($OptionListName, $FieldTypes=NULL, $SelectedFieldId=NULL, $IncludeNullOption=TRUE, $AddEntries=NULL, $AllowMultiple=FALSE)
Retrieve fields of specified type as HTML option list with field names as labels and field IDs as val...
static SchemaExistsWithId($SchemaId)
Check with schema exists with specified ID.
static FieldToStdNameMapping($FieldId)
Get mapping of field ID to standard field name.
const MDFSTAT_FIELDDOESNOTEXIST
FieldExists($FieldName)
Check whether field with specified name exists.
CompareFieldOrder($FieldA, $FieldB)
Field sorting callback.
GetFieldIdByMappedName($MappedName)
Get field ID by standard field name.
Set of privileges used to access resource information or other parts of the system.
GetFieldNames($FieldTypes=NULL, $OrderType=NULL, $IncludeDisabledFields=FALSE, $IncludeTempFields=FALSE)
Retrieve field names.
static $DefaultEditOrder
The default editing order for metadata fields.
AddFieldFromXml($Xml)
Add new metadata field based on supplied XML.
CacheData($NewValue)
Enable/disable caching of metadata field info.
static SetOwnerListRetrievalFunction($Callback)
Allow external dependencies, i.e., the current list of owners that are available, to be injected...
MetadataSchema($SchemaId=self::SCHEMAID_DEFAULT)
Object constructor, used to load an existing schema.
Name($NewValue=NULL)
Get/set name of schema.
ViewPage($NewValue=NULL)
Get/set name of page to go to for viewing resources using this schema.
const MDFTYPE_CONTROLLEDNAME
GetOwnedFields()
Get fields that have an owner associated with them.
PathMatchesViewPage($Path)
Determine if a path matches the view page path for the schema.
PHP
Definition: OAIClient.php:39
const MDFSTAT_DUPLICATEDBCOLUMN
GetEditOrder()
Get the editing order for the schema.
static $DefaultDisplayOrder
The default display order for metadata fields.
static $OwnerListRetrievalFunction
const MDFSTAT_DUPLICATELABEL
static Create(MetadataSchema $Schema, $Name, array $FieldOrder=array())
Create a new metadata field order, optionally specifying the order of the fields. ...
NewFields()
Get new fields recently added (if any) via XML file.
AddField($FieldName, $FieldType, $Optional=TRUE, $DefaultValue=NULL)
Add new metadata field.
GetFields($FieldTypes=NULL, $OrderType=NULL, $IncludeDisabledFields=FALSE, $IncludeTempFields=FALSE)
Retrieve array of fields.
GetDisplayOrder()
Get the display order for the schema.
FieldCompareOrdersSet()
Determine whether the field comparison ordering caches are set.
static Create($Name, PrivilegeSet $AuthorPrivs=NULL, PrivilegeSet $EditPrivs=NULL, PrivilegeSet $ViewPrivs=NULL, $ViewPage="", $ResourceName=NULL)
Create new metadata schema.
Object representing a locally-defined type of metadata field.
static GetRowsForUpgrade($Type)
Get rows for upgrading purposes.
AuthoringPrivileges(PrivilegeSet $NewValue=NULL)
Get/set privileges that allowing authoring resources with this schema.
DropField($FieldId)
Delete metadata field and all associated data.
RemoveQualifierAssociations($QualifierIdOrObject)
Remove all metadata field associations for a given qualifier.
UpdateFieldCompareOrders()
Update the field comparison ordering cache that is used for sorting fields.
static GetOrderForSchema(MetadataSchema $Schema, $Name)
Get a metadata field order with a specific name for a given metadata schema.
const MDFSTAT_ILLEGALNAME
GetField($FieldId)
Retrieve metadata field by ID.
GetFieldByMappedName($MappedName)
Get field by standard field name.
Id()
Get schema ID.
AddFieldsFromXmlFile($FileName, $TestRun=FALSE)
Add new metadata fields from XML file.
Common factory class for item manipulation.
Definition: ItemFactory.php:17
const MDFSTAT_DUPLICATENAME
$FieldCompareDisplayOrder
The cache for metadata field display ordering.
NameIsInUse($Name, $IgnoreCase=FALSE)
Check whether item name is currently in use.
static DisplayQueryErrors($NewValue=NULL)
Get/set whether Query() errors will be displayed.
static StdNameToFieldMapping($MappedName, $FieldId=NULL)
Get/set mapping of standard field name to specific field.
GetFieldTypes()
Retrieve array of field types.
ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName, $ItemNameFieldName=NULL, $OrderOpsAllowed=FALSE, $SqlCondition=NULL)
Class constructor.
Definition: ItemFactory.php:36
static GetAllSchemas()
Get all existing metadata schemas.
GetFieldByLabel($FieldLabel, $IgnoreCase=FALSE)
Retrieve metadata field by label.
QualifierIsInUse($QualifierIdOrObject)
Check whether qualifier is in use by any metadata field (in any schema).