/Main_Page

::You must have ninja focus to complete your mission::NinjaFocus::

EZ Publish Import Operator

Views:


This is part of an extention to eZ Publish to allow the automatic CRUD of content. While makeing the extension a good deal of inspiration and a certain amount of code was taken from the Data Import Extension for eZ Publish, written by Marius Eliassen and Philipp Kamps.

It relies on PHP Error Handling and PHP Patterns.

<?php 
/**
 * @package eZData
 * @copyright Kieran Whitbread 2009-2010
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */
abstract class eZData_ImportOperator {
    
    protected $source = null;
    protected $userId = 14; // 14 = the Administrator User.
    protected $targetContentClass = null;
    protected $targetLanguage = null;
    protected $parentNode = 261;
    protected $contentObject = null;
    protected $contentObjectVersion = null;
    protected $nodePriority = 0;
    
    public function __construct(eZData_Model $source)
    {
        $this->source = $source;
        if (eZUser::currentUserID() !== $this->getUserId())
        {
            $user = eZUser::fetch($this->getUserId());
            eZUser::setCurrentlyLoggedInUser($user, $this->getUserId());
        }
    }
    protected function createContentObject()
    {
        if (!$this->contentObject)
        {
            $class = eZContentClass::fetchByIdentifier($this->getTargetContentClass());
            if($class)
            {
                $object = $class->instantiate($this->getUserId(), 0, false, $this->targetLanguage);
                if (!$object)
                {
                    trigger_error("Could not create new eZContent Object using eZContentClass id '{$this->getTargetContentClass()}'", E_USER_ERROR);
                }
                $object->setAttribute('remote_id', $this->source->getRemoteId());
                $object->store();
                $this->contentObject = $object;
                $this->contentObject->fetchDataMap();
            }
            else
            {
                trigger_error("Could not create an instance of eZContentClass using id '{$this->getTargetContentClass()}'", E_USER_ERROR);
            }
        }
        return $this->contentObject;
    }
    protected function createContentObjectVersion()
    {
        if ($this->contentObject)
        {
            $version = $this->contentObject->createNewVersion(false, false, $this->getTargetLanguage());
            $this->contentObjectVersion = $version;
            if (!$this->contentObjectVersion)
            {
                trigger_error("Unable to create a new Content Object Version", E_USER_WARNING);
            }
            return $this->contentObjectVersion;
        }
        else
        {
            trigger_error("There is no content object available", E_USER_ERROR);
        }
    }
    /**
     * fetches an instance of an eZ Publish Content Object.
     *
     * @return eZContentObject
     * @author Kieran Whitbread
     **/
    protected function getContentObject()
    {
        if (!$this->contentObject)
        {
            $this->contentObject = eZContentObject::fetchByRemoteID($this->source->getRemoteId());
            if (!$this->contentObject)
            {
                return null;
            }
            $this->contentObject->setAttribute('owner_id', $this->getUserId());
            $this->contentObject->store();
            $this->contentObject->fetchDataMap();
        }
        return $this->contentObject;
    }
    protected function getContentObjectVersion()
    {
        if ($this->contentObject)
        {
            $version = $this->contentObject->currentVersion();
            $this->contentObjectVersion = $version;
        }
        return $this->contentObjectVersion;
    }
    /**
     * @deprecated
     * @return void
     * @author Kieran Whitbread
     **/
    protected function getDataTypeForAttribute(eZContentObjectAttribute $attribute)
    {
        $attrDatatype = $attribute->attribute('data_type_string');
        switch ($attrDatatype)
        {
            case 'ezboolean':
                                            $dataType = 'data_int';
                                            break;
            case 'ezdate':
                                            $dataType = 'data_int';
                                            break;
            case 'ezdatetime':
                                            $dataType = 'data_int';
                                            break;
            case 'ezimage':
                                            $dataType = 'data_text';
                                            break;
            case 'ezinteger':
                                            $dataType = 'data_int';
                                            break;
            case 'ezisbn':
                                            $dataType = 'data_text';
                                            break;
            case 'ezkeyword':
                                            $dataType = false;
                                            break;
            case 'ezobjectrelation':      
                                            $dataType = false;
                                            break;
            case 'ezobjectrelationlist':    
                                            $dataType = false;
                                            break;
            case 'ezstring':
                                            $dataType = 'data_text';
                                            break;
            case 'ezurl':
                                            $dataType = 'data_text';
                                            break;
            default:                        
                                            $dataType = false;
                                            break;
        }
        return $dataType;
    }
    public function getNodePriority()
    {
        return $this->nodePriority;
    }
    public function getParentNodeId()
    {
        return $this->parentNode;
    }
    public function getTargetContentClass()
    {
        return $this->targetContentClass;
    }
    public function getTargetLanguage()
    {
        return $this->targetLanguage;
    }
    public function getUserId()
    {
        return $this->userId;
    }
    public function import($updateExisting = true)
    {
        if (!$this->contentObject)
        {
            $this->getContentObject();
            if ($this->contentObject  && !$updateExisting)
            {
                return null;
            }
            elseif ($this->contentObject)
            {
                // There was an existing object we could load, therefore our changes should be made to 
                // a new version of the object.
                $this->createContentObjectVersion();
            }
            elseif (!$this->contentObject)
            {
                // Could not load an existing object, try to create one
                $this->createContentObject();
                // it's a new object so make changes to the initial "version 1"
                // which was created at the same time as the object was created.
                $this->getContentObjectVersion();
            }
        }
        if (!$this->contentObject)
        {
            NinjaError::trigger(__METHOD__." could neither load nor create content object", E_USER_ERROR, 1);
            return null;
        }
        if (!$this->contentObject->attribute('main_node_id'))
        {
            // this object is new or was pulled out of the archive and has no node assignment. make one.
            // Assign object to node
            $nodeAssignment = eZNodeAssignment::create(
                array(
                    'contentobject_id'      => $this->contentObject->attribute('id'),
                    'contentobject_version' => $this->contentObjectVersion->attribute('version'),
                    'parent_node' => $this->getParentNodeId(),
                    'is_main' => 1,
                    'user_id' => $this->getUserId(),
                )
            );
            if($nodeAssignment)
            {
                $nodeAssignment->store();
                $this->contentObject->sync();
            }
        }
        $nodes = $this->contentObject->attribute('assigned_nodes');
        foreach ($nodes as $node)
        {
            if ($node->attribute('main_node_id') == $node->attribute('node_id') && $node->attribute('is_hidden'))
            {
                eZContentObjectTreeNode::unhideSubTree($node);
            }
        }
        
        $this->updateContentObject();
        $this->updateNodePriority();
        $this->contentObject->store();
        $this->publish();
        $this->updateNodePriority();
        ezContentObject::clearCache($this->contentObject->attribute('id'));
        eZContentCacheManager::clearContentCache($this->contentObject->attribute('id'));
    }
    protected function prepareAttributeForValue(eZContentObjectAttribute $attribute, $value)
    {
        $attrDatatype = $attribute->attribute('data_type_string');
        switch ($attrDatatype)
        {
            case 'ezurl':
                                            // NOOP
                                            break;
            case 'ezkeyword':
                                            // NOOP
                                            break;

            case 'ezdate':
                                            // NOOP
                                            break;
            case 'ezdatetime':
                                            // NOOP
                                            break;
            case 'ezobjectrelation':      
                                            // Remove any exisiting value first from ezobjectrelation
                                            $attribute->setAttribute('data_int', 0);
                                            $attribute->store();
                                            break;
            case 'ezobjectrelationlist':    
                                            // Remove any exisiting value first from ezobjectrelationlist
                                            $content = $attribute->content();
                                            $relationList =& $content['relation_list'];
                                            $newRelationList = array();
                                            for ($i = 0; $i < count($relationList); ++$i )
                                            {
                                                $relationItem = $relationList[$i];
                                                eZObjectRelationListType::removeRelationObject(
                                                    $attribute, 
                                                    $relationItem
                                                );
                                            }
                                            $content['relation_list'] =& $newRelationList;
                                            $attribute->setContent($content);
                                            $attribute->store();
                                            break;
        }
        return $attribute;
    }
    protected function prepareValueForAttribute($value, eZContentObjectAttribute $attribute)
    {
        $attrDatatype = $attribute->attribute('data_type_string');
        switch ($attrDatatype)
        {
            case 'ezxmltext':               $parser = new eZSimplifiedXMLInputParser(null);
                                            $document = $parser->process($value);
                                            $value = eZXMLTextType::domString($document);
                                            break;
            case 'ezurl':
                                            // NOOP
                                            break;
            case 'ezkeyword':
                                            $keyword = new eZKeyword();
                                            $keyword->initializeKeyword($value);
                                            $value = $keyword;
                                            break;
            case 'ezdate':                  
                                            $value = strtotime($value);
                                            break;
            case 'ezdatetime':
                                            $value = strtotime($value);
                                            break;
        }
        return $value;
    }
    public function publish()
    {
        if ($this->contentObject && $this->contentObjectVersion)
        {
            return eZOperationHandler::execute(
                'content',
                'publish',
                array(
                     'object_id' => $this->contentObject->attribute('id'),
                     'version'   => $this->contentObjectVersion->attribute('version'),
                     'user_id' => $this->getUserId(),
                    )
            );
        }
        trigger_error("No eZContentObject and/or eZContentObject version to publish", E_USER_WARNING);
        return false;
    }
    public function remove()
    {
        if (!$this->contentObject)
        {
            $this->getContentObject();
            $this->getContentObjectVersion();
        }
        if ($this->contentObject)
        {
            eZContentCacheManager::clearContentCacheIfNeeded($this->contentObject->attribute('id'));
            $this->contentObject->removeThis();
        }
    }

    /**
     * Set the priority of the node, used for specifying an arbitrary sort order of content inside a 
     * container class inside eZ Publish.
     *
     * @param int $priority the priority by of this node in relation to any other nodes.
     * @return void
     * @author Kieran Whitbread
     **/
    public function setNodePriority($priority)
    {
        if (preg_match(NINJA_PREG_UINT, $priority))
        {
            $this->nodePriority = $priority;
        }
        else
        {
            NinjaError::trigger(__METHOD__." expects parameter one to be an unsigned integer", E_USER_ERROR, 1);
        }
    }
    /**
     * The node id of the parent container content object (e.g. a Folder) where the new node will be placed.
     *
     * @param int $id the Id of the parent node
     * @return void
     * @author Kieran Whitbread
     **/
    public function setParentNodeId($id)
    {
        if (preg_match(NINJA_PREG_UNIT, $id))
        {
            $this->parentNodeId = $id;
        }
        else
        {
            NinjaError::trigger(__METHOD__." expects parameter one to be an unsigned integer", E_USER_ERROR, 1);
        }
    }
    public function setUserId($id)
    {
        $this->userId = $id;
    }
    protected function updateNodePriority()
    {
        $priority = $this->getNodePriority();
        if(!is_null($priority) && $this->contentObject)
        {
            $parentId = $this->getParentNodeId();
            $assignedNodes = $this->contentObject->attribute('assigned_nodes'); 
            $db = eZDB::instance();
            foreach($assignedNodes as $assignedNode)
            {
                $parent = $assignedNode->attribute('parent');
                if($parent && $parent->attribute('node_id') == $parentId)
                {
                    $db->begin();
                    $nodeID = $assignedNode->attribute('node_id');
                    $db->query("UPDATE `ezcontentobject_tree` SET `priority` = $priority WHERE `node_id` = $nodeID");
                    $assignedNode->updateAndStoreModified();
                    $db->commit();
                }
            }
        }
    }
    protected function updateContentObject()
    {
        $dataMap = $this->contentObjectVersion->attribute('data_map');
        $availableAttributes = $this->source->getAvailableAttributes();
        foreach ($availableAttributes as $attributeName)
        {
            $attribute = $dataMap[$attributeName];
            if($attribute)
            {
                $value = $this->source->getAttributeValue($attributeName);
                $value = $this->prepareValueForAttribute($value, $attribute);
                $attribute = $this->prepareAttributeForValue($attribute, $value);
                $this->updateContentObjectAttribute($attribute, $value);
            }
            else
            {
                trigger_error("$attributeName does not exist in the content object", E_USER_WARNING);
            }
        }
    }
    protected function updateContentObjectAttribute(eZContentObjectAttribute $attribute, $value)
    {
        // no longer treating everything as a string.
        //$attribute->fromString($value);
        
        // Now we try to determine which internal datatype ez publish will be using for this 
        // attribute.
        $attrDatatype = $attribute->attribute('data_type_string');
        switch ($attrDatatype)
        {
            case 'ezboolean':
                                            $attribute->setAttribute('data_int', $value);
                                            break;
            case 'ezdate':
                                            $attribute->setAttribute('data_int', $value);
                                            break;
            case 'ezdatetime':
                                            $attribute->setAttribute('data_int', $value);
                                            break;
            case 'ezimage':
                                            $attribute->fromString($value);
                                            break;
            case 'ezinteger':
                                            $attribute->setAttribute('data_int', $value);
                                            break;
            case 'ezisbn':
                                            $attribute->setAttribute('data_text', $value);
                                            break;
            case 'ezkeyword':
                                            $attribute->fromString($value);
                                            break;
            case 'ezobjectrelationlist':    
                                            if (is_array($value))
                                            {
                                                $attribute->fromString(implode('-', $value));
                                            }
                                            else
                                            {
                                                $attribute->fromString($value);
                                            }
                                            break;
            case 'ezstring':
                                            $attribute->setAttribute('data_text', $value);
                                            break;
            case 'ezurl':
                                            $attribute->setAttribute('data_text', $value);
                                            break;
            case 'ezxmltext':
                                            $attribute->fromString($value);
                                            break;
            default:                        
                                            $attribute->fromString($value);
                                            break;
        }
        $attribute->store();
    }
}

Main Menu

Personal tools

Toolbox