1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 
<?php
namespace Omeka\Installation\Task;

use Omeka\Api\Manager as ApiManager;
use Omeka\Installation\Installer;

/**
 * Install default resource templates.
 */
class InstallDefaultTemplatesTask implements TaskInterface
{
    /**
     * @var \Omeka\Api\Manager
     */
    protected $api;

    /**
     * @var array Cached properties
     */
    protected $cache = [];

    /**
     * Default resource templates.
     *
     * Keys are the (unique) template labels. Values are arrays containing:
     *
     * - prefix: vocabulary prefix (required)
     * - local_name: property local name (required)
     * - alternate_label: template alternate label (optional)
     * - alternate_comment: template alternate comment (optional)
     *
     * @var array
     */
    protected $templates = [
        /*
         * The "Base Resource" resource template, comprising recommended
         * properties for a dpla:SourceResource as described by DPLA's Metadata
         * Application Profile (MAP) version 4.0. These properties are roughly
         * ordered by importance (required, recommended, and optional).
         */
        'Base Resource' => [
            ['prefix' => 'dcterms', 'local_name' => 'title'],
            ['prefix' => 'dcterms', 'local_name' => 'rights'],
            ['prefix' => 'dcterms', 'local_name' => 'type'],
            ['prefix' => 'dcterms', 'local_name' => 'creator'],
            ['prefix' => 'dcterms', 'local_name' => 'date'],
            ['prefix' => 'dcterms', 'local_name' => 'description'],
            ['prefix' => 'dcterms', 'local_name' => 'format'],
            ['prefix' => 'dcterms', 'local_name' => 'language'],
            ['prefix' => 'dcterms', 'local_name' => 'spatial', 'alternate_label' => 'Place'],
            ['prefix' => 'dcterms', 'local_name' => 'publisher'],
            ['prefix' => 'dcterms', 'local_name' => 'alternative'],
            ['prefix' => 'dcterms', 'local_name' => 'contributor'],
            ['prefix' => 'dcterms', 'local_name' => 'extent'],
            ['prefix' => 'dcterms', 'local_name' => 'identifier'],
            ['prefix' => 'dcterms', 'local_name' => 'relation'],
            ['prefix' => 'dcterms', 'local_name' => 'isReplacedBy'],
            ['prefix' => 'dcterms', 'local_name' => 'replaces'],
            ['prefix' => 'dcterms', 'local_name' => 'rightsHolder'],
            ['prefix' => 'dcterms', 'local_name' => 'subject'],
            ['prefix' => 'dcterms', 'local_name' => 'temporal'],
        ],
    ];

    public function perform(Installer $installer)
    {
        $this->setApi($installer->getServiceLocator()->get('Omeka\ApiManager'));
        foreach (array_keys($this->templates) as $label) {
            $this->installTemplate($label);
        }
    }

    /**
     * Install a default resource template.
     *
     * @param string $label A label of a template defined in this class
     * @return null|false Returns false if the label does not exist
     */
    public function installTemplate($label)
    {
        if (!isset($this->templates[$label])) {
            return false;
        }

        $resTemProps = [];
        foreach ($this->templates[$label] as $property) {
            if (!isset($this->cache[$property['prefix']])) {
                // Cache this vocabulary's properties.
                $this->cacheProperties($property['prefix']);
            }
            if (!isset($property['prefix']) || !isset($property['local_name'])) {
                // Must have vocabulary prefix and property local name.
                continue;
            }
            $propertyId = $this->cache[$property['prefix']][$property['local_name']];
            $altLabel = null;
            if (isset($property['alternate_label'])) {
                $altLabel = $property['alternate_label'];
            }
            $altComment = null;
            if (isset($property['alternate_comment'])) {
                $altComment = $property['alternate_comment'];
            }
            $resTemProps[] = [
                'o:property' => ['o:id' => $propertyId],
                'o:alternate_label' => $altLabel,
                'o:alternate_comment' => $altComment,
            ];
        }

        $this->getApi()->create('resource_templates', [
            'o:label' => $label,
            'o:resource_template_property' => $resTemProps,
        ]);
    }

    protected function cacheProperties($prefix)
    {
        $properties = $this->getApi()
            ->search('properties', ['vocabulary_prefix' => $prefix])
            ->getContent();
        foreach ($properties as $property) {
            $this->cache[$prefix][$property->localName()] = $property->id();
        }
    }

    protected function getApi()
    {
        if (!$this->api) {
            throw new \RuntimeException('The API manager must be set to this task.');
        }
        return $this->api;
    }

    public function setApi(ApiManager $api)
    {
        $this->api = $api;
    }
}