Пример #1
0
 private function trash_list()
 {
     $params = false;
     $asCount = false;
     $trashObjects = eZContentObjectTrashNode::trashList($params, $asCount);
     eep::displayNodeList($trashObjects, "Garbage Nodes");
 }
    /**
     * Regression test for issue #16737
     * 1) Test executing the sql and verify that it doesn't have database error.
     * 2) Test the sorting in class_name, class_name with contentobject_id
     * The test should pass in mysql, postgresql and oracle
     */
    public function testIssue16737()
    {


        //test generated result of createSortingSQLStrings
        $sortList = array( array( 'class_name', true ) );
        $result = eZContentObjectTreeNode::createSortingSQLStrings( $sortList );
        $this->assertEquals( ', ezcontentclass_name.name as contentclass_name',
                            strtolower( $result['attributeTargetSQL'] ) );
        $this->assertEquals( 'contentclass_name asc', strtolower( $result['sortingFields'] ) );

        $sortListTwo = array( array( 'class_name', false ),
                              array( 'class_identifier', true ) );
        $result = eZContentObjectTreeNode::createSortingSQLStrings( $sortListTwo );
        $this->assertEquals( ', ezcontentclass_name.name as contentclass_name',
                            strtolower( $result['attributeTargetSQL'] ));
        $this->assertEquals( 'contentclass_name desc, ezcontentclass.identifier asc',
                            strtolower( $result['sortingFields'] ) );

        //test trash node with classname
        $sortBy = array( array( 'class_name', true ),
                         array( 'contentobject_id', true ) );
        $params = array( 'SortBy', $sortBy );
        $result = eZContentObjectTrashNode::trashList( $params );
        $this->assertEquals( array(), $result );
        $result = eZContentObjectTrashNode::trashList( $params, true );
        $this->assertEquals( 0, $result );  //if there is an error, there will be fatal error message

        //test subtreenode with classname
        $parent = new ezpObject( 'folder', 1 );
        $parent->publish();
        $parentNodeID = $parent->mainNode->node_id;

        $article = new ezpObject( 'article', $parentNodeID );
        $article->publish();

        $link = new ezpObject( 'link', $parentNodeID );
        $link->publish();

        $folder = new ezpObject( 'folder', $parentNodeID );
        $folder->publish();

        $folder2 = new ezpObject( 'folder', $parentNodeID );
        $folder2->publish();

        $sortBy = array( array( 'class_name', false ) );
        $params = array( 'SortBy' => $sortBy );
        $result = eZContentObjectTreeNode::subTreeByNodeID( $params, $parentNodeID );
        $this->assertEquals( $article->mainNode->node_id, $result[count( $result )-1]->attribute( 'node_id' ) );

        $sortBy = array( array( 'class_name', false ),
                         array( 'contentobject_id', false ) );
        $params = array( 'SortBy' => $sortBy );
        $result = eZContentObjectTreeNode::subTreeByNodeID( $params, $parentNodeID );
        $this->assertEquals( $folder2->mainNode->node_id, $result[1]->attribute( 'node_id' ) );
    }
 /**
  * Unit test for eZContentObject::relatedObjectCount()
  *
  * Outline:
  * 1) Create a content class with ezobjectrelation and ezobjectrelationlist
  *    attributes
  * 2) Create objects and relate them to each of these attributes and to the
  *    object itself (common)
  * 3) Check that attribute count is correct on each attribute and globally
  */
 public function testRelatedObjectCount()
 {
     // Create a test content class
     $class = new ezpClass(__FUNCTION__, __FUNCTION__, 'name');
     $class->add('Name', 'name', 'ezstring');
     $attributes['single_relation_1'] = $class->add('Single relation #1', 'single_relation_1', 'ezobjectrelation')->attribute('id');
     $attributes['single_relation_2'] = $class->add('Single relation #2', 'single_relation_2', 'ezobjectrelation')->attribute('id');
     $attributes['multiple_relations_1'] = $class->add('Multiple relations #1', 'multiple_relations_1', 'ezobjectrelationlist')->attribute('id');
     $attributes['multiple_relations_2'] = $class->add('Multiple relations #2', 'multiple_relations_2', 'ezobjectrelationlist')->attribute('id');
     $class->store();
     // create a few articles we will relate our object to
     $relatedObjects = array();
     for ($i = 0; $i < 10; $i++) {
         $article = new ezpObject('article', 2);
         $article->title = "Related object #'{$i} for " . __FUNCTION__;
         $article->publish();
         $relatedObjects[] = $article->attribute('id');
     }
     // Create a test object with various relations (some objects are related
     // to multiple attributes in order to test reverse relations):
     // - 1 relation (IDX 0) on single_relation_1
     // - 1 relation (IDX 1) on single_relation_2
     // - 2 relations (IDX 2, 3) on multiple_relations_1
     // - 2 relations (IDX 4, 5) on multiple_relations_2
     // - 6 object level relations ((IDX 6, 7, 8, 9)
     $object = new ezpObject(__FUNCTION__, 2);
     $object->name = __FUNCTION__;
     $object->single_relation_1 = $relatedObjects[0];
     $object->single_relation_2 = $relatedObjects[1];
     $object->multiple_relations_1 = array($relatedObjects[0], $relatedObjects[2], $relatedObjects[3]);
     $object->multiple_relations_2 = array($relatedObjects[1], $relatedObjects[4], $relatedObjects[5]);
     $object->addContentObjectRelation($relatedObjects[0]);
     $object->addContentObjectRelation($relatedObjects[1]);
     $object->addContentObjectRelation($relatedObjects[6]);
     $object->addContentObjectRelation($relatedObjects[7]);
     $object->addContentObjectRelation($relatedObjects[8]);
     $object->addContentObjectRelation($relatedObjects[9]);
     $object->publish();
     // Create 2 more objects with relations to $relatedObjects[9]
     // in order to test reverse related objects
     $otherObject1 = new ezpObject(__FUNCTION__, 2);
     $otherObject1->name = "Reverse test object #1 for " . __FUNCTION__;
     $otherObject1->single_relation_1 = $relatedObjects[9];
     $otherObject1->publish();
     $otherObject2 = new ezpObject(__FUNCTION__, 2);
     $otherObject2->name = "Reverse test object #2 for " . __FUNCTION__;
     $otherObject2->single_relation_2 = $relatedObjects[9];
     $otherObject2->publish();
     $contentObject = eZContentObject::fetch($object->attribute('id'));
     $paramAllRelations = array('AllRelations' => true);
     $paramAttributeRelations = array('AllRelations' => eZContentObject::RELATION_ATTRIBUTE);
     $paramCommonRelations = array('AllRelations' => eZContentObject::RELATION_COMMON);
     // Test overall relation count
     $this->assertEquals(14, $contentObject->relatedObjectCount(false, false, false, $paramAllRelations), "Overall relation count should be 14");
     // Test relation count for each attribute
     $this->assertEquals(1, $contentObject->relatedObjectCount(false, $attributes['single_relation_1'], false, $paramAttributeRelations), "Relation count on attribute single_relation_1 should be 1");
     $this->assertEquals(1, $contentObject->relatedObjectCount(false, $attributes['single_relation_2'], false, $paramAttributeRelations), "Relation count on attribute single_relation_2 should be 1");
     $this->assertEquals(3, $contentObject->relatedObjectCount(false, $attributes['multiple_relations_1'], false, $paramAttributeRelations), "Relation count on attribute multiple_relations_1 should be 3");
     $this->assertEquals(3, $contentObject->relatedObjectCount(false, $attributes['multiple_relations_2'], false, $paramAttributeRelations), "Relation count on attribute multiple_relations_2 should be 3");
     // Test common level relation count
     $this->assertEquals(6, $contentObject->relatedObjectCount(false, false, false, $paramCommonRelations), "Common relations count should be 6");
     // Test reverse relation count on $relatedObject[9]
     // This object is related to:
     // - the main $object on common level
     // - one object on single_relation_1
     // - another object on single_relation_2
     $relatedContentObject = eZContentObject::fetch($relatedObjects[9]);
     $this->assertEquals(3, $relatedContentObject->relatedObjectCount(false, false, true, $paramAllRelations), "Overall reverse relation count should be 3");
     $this->assertEquals(1, $relatedContentObject->relatedObjectCount(false, false, true, $paramCommonRelations), "Common reverse relation count should be 1");
     $this->assertEquals(1, $relatedContentObject->relatedObjectCount(false, $attributes['single_relation_1'], true, $paramAttributeRelations), "Attribute reverse relation count on single_relation_1 should be 1");
     $this->assertEquals(1, $relatedContentObject->relatedObjectCount(false, $attributes['single_relation_2'], true, $paramAttributeRelations), "Attribute reverse relation count on single_relation_2 should be 1");
     // Test that trashed objects are not counted as related (issue #15142)
     $trashObject = eZContentObject::fetch($relatedObjects[9]);
     $trashObject->removeThis();
     $this->assertEquals(13, $contentObject->relatedObjectCount(false, false, false, $paramAllRelations), "Relation count after move to trash should be 13");
     // Empty the trash
     foreach (eZContentObjectTrashNode::trashList() as $node) {
         eZContentObjectTrashNode::purgeForObject($node->attribute('contentobject_id'));
     }
 }
 public static function fetchTrashObjectList($offset, $limit, $objectNameFilter, $attributeFilter = false, $sortBy = false, $asObject = true)
 {
     $params = array();
     if ($objectNameFilter !== false) {
         $params['ObjectNameFilter'] = $objectNameFilter;
     }
     $params['Limit'] = $limit;
     $params['Offset'] = $offset;
     $params['AttributeFilter'] = $attributeFilter;
     $params['SortBy'] = $sortBy;
     $params['AsObject'] = $asObject;
     $trashNodesList = eZContentObjectTrashNode::trashList($params, false);
     return array('result' => $trashNodesList);
 }
Пример #5
0
    $object->store();
    $version->setAttribute('status', eZContentObjectVersion::STATUS_DRAFT);
    $version->store();
    $user = eZUser::currentUser();
    $operationResult = eZOperationHandler::execute('content', 'publish', array('object_id' => $objectID, 'version' => $version->attribute('version')));
    if (array_key_exists('status', $operationResult) && $operationResult['status'] != eZModuleOperationInfo::STATUS_CONTINUE) {
        switch ($operationResult['status']) {
            case eZModuleOperationInfo::STATUS_HALTED:
            case eZModuleOperationInfo::STATUS_CANCELLED:
                $module->redirectToView('trash');
        }
    }
    $objectID = $object->attribute('id');
    $object = eZContentObject::fetch($objectID);
    $mainNodeID = $object->attribute('main_node_id');
    eZContentObjectTrashNode::purgeForObject($objectID);
    if ($locationAdded) {
        if ($object->attribute('contentclass_id') == $userClassID) {
            eZUser::purgeUserCacheByUserId($object->attribute('id'));
        }
    }
    eZContentObject::fixReverseRelations($objectID, 'restore');
    $db->commit();
    $module->redirectToView('view', array('full', $mainNodeID));
    return;
}
$tpl = eZTemplate::factory();
$res = eZTemplateDesignResource::instance();
$designKeys = array(array('object', $object->attribute('id')), array('remote_id', $object->attribute('remote_id')), array('class', $class->attribute('id')), array('class_identifier', $class->attribute('identifier')));
// Class identifier
$res->setKeys($designKeys);
 /**
  * Returns the number of nodes in the trash
  *
  * @param array|bool $params
  * @return int
  */
 static function trashListCount($params = false)
 {
     return eZContentObjectTrashNode::trashList($params, true);
 }
Пример #7
0
 static function removeRelationObject($contentObjectAttribute, $deletionItem)
 {
     if (self::isItemPublished($deletionItem)) {
         return;
     }
     $hostObject = $contentObjectAttribute->attribute('object');
     $hostObjectID = $hostObject->attribute('id');
     // Do not try removing the object if present in trash
     // Only objects being really orphaned (not even being in trash) should be removed by this method.
     // See issue #019457
     if ((int) eZPersistentObject::count(eZContentObjectTrashNode::definition(), array("contentobject_id" => $hostObjectID)) > 0) {
         return;
     }
     $hostObjectVersions = $hostObject->versions();
     $isDeletionAllowed = true;
     // check if the relation item to be deleted is unique in the domain of all host-object versions
     foreach ($hostObjectVersions as $version) {
         if ($isDeletionAllowed and $version->attribute('version') != $contentObjectAttribute->attribute('version')) {
             $relationAttribute = eZPersistentObject::fetchObjectList(eZContentObjectAttribute::definition(), null, array('version' => $version->attribute('version'), 'contentobject_id' => $hostObjectID, 'contentclassattribute_id' => $contentObjectAttribute->attribute('contentclassattribute_id')));
             if (count($relationAttribute) > 0) {
                 $relationContent = $relationAttribute[0]->content();
                 if (is_array($relationContent) and is_array($relationContent['relation_list'])) {
                     foreach ($relationContent['relation_list'] as $relationItem) {
                         if ($deletionItem['contentobject_id'] == $relationItem['contentobject_id'] && $deletionItem['contentobject_version'] == $relationItem['contentobject_version']) {
                             $isDeletionAllowed = false;
                             break 2;
                         }
                     }
                 }
             }
         }
     }
     if ($isDeletionAllowed) {
         $subObjectVersion = eZContentObjectVersion::fetchVersion($deletionItem['contentobject_version'], $deletionItem['contentobject_id']);
         if ($subObjectVersion instanceof eZContentObjectVersion) {
             $subObjectVersion->removeThis();
         } else {
             eZDebug::writeError('Cleanup of subobject-version failed. Could not fetch object from relation list.\\n' . 'Requested subobject id: ' . $deletionItem['contentobject_id'] . '\\n' . 'Requested Subobject version: ' . $deletionItem['contentobject_version'], __METHOD__);
         }
     }
 }
Пример #8
0
 /**
  * Executes the purge operation
  *
  * @param int|null $iterationLimit Number of trashed objects to treat per iteration, use null to use a default value.
  * @param int|null $sleep Number of seconds to sleep between two iterations, use null to use a default value.
  *
  * @return bool True if the operation succeeded.
  */
 public function run($iterationLimit = 100, $sleep = 1)
 {
     if ($iterationLimit === null) {
         $iterationLimit = 100;
     }
     if ($sleep === null) {
         $sleep = 1;
     }
     if ($this->memoryMonitoring) {
         eZLog::rotateLog($this->logFile);
         $this->cli->output("Logging memory usage to {$this->logFile}");
     }
     $this->cli->output("Purging trash items:");
     $this->monitor("start");
     $db = eZDB::instance();
     // Get user's ID who can remove subtrees. (Admin by default with userID = 14)
     $userCreatorID = eZINI::instance()->variable("UserSettings", "UserCreatorID");
     $user = eZUser::fetch($userCreatorID);
     if (!$user) {
         $this->cli->error("Cannot get user object with userID = '{$userCreatorID}'.\n(See site.ini[UserSettings].UserCreatorID)");
         return false;
     }
     eZUser::setCurrentlyLoggedInUser($user, $userCreatorID);
     $trashCount = eZContentObjectTrashNode::trashListCount(false);
     if (!$this->quiet) {
         $this->cli->output("Found {$trashCount} object(s) in trash.");
     }
     if ($trashCount == 0) {
         return true;
     }
     if ($this->script !== null) {
         $this->script->resetIteration($trashCount);
     }
     while ($trashCount > 0) {
         $this->monitor("iteration start");
         $trashList = eZContentObjectTrashNode::trashList(array('Limit' => $iterationLimit), false);
         $db->begin();
         foreach ($trashList as $trashNode) {
             $object = $trashNode->attribute('object');
             $this->monitor("purge");
             $object->purge();
             if ($this->script !== null) {
                 $this->script->iterate($this->cli, true);
             }
         }
         if (!$db->commit()) {
             $this->cli->output();
             $this->cli->error('Trash has not been emptied, impossible to commit the whole transaction');
             return false;
         }
         $trashCount = eZContentObjectTrashNode::trashListCount(false);
         if ($trashCount > 0) {
             eZContentObject::clearCache();
             if ($sleep > 0) {
                 sleep($sleep);
             }
         }
         $this->monitor("iteration end");
     }
     if (!$this->quiet) {
         $this->cli->output('Trash successfully emptied');
     }
     $this->monitor("end");
     return true;
 }
 function removeNodeFromTree($moveToTrash = true)
 {
     $nodeID = $this->attribute('node_id');
     $object = $this->object();
     $assignedNodes = $object->attribute('assigned_nodes');
     if ($nodeID == $this->attribute('main_node_id')) {
         if (count($assignedNodes) > 1) {
             $newMainNode = false;
             foreach ($assignedNodes as $assignedNode) {
                 $assignedNodeID = $assignedNode->attribute('node_id');
                 if ($assignedNodeID == $nodeID) {
                     continue;
                 }
                 $newMainNode = $assignedNode;
                 break;
             }
             // We need to change the main node ID before we remove the current node
             $db = eZDB::instance();
             $db->begin();
             eZContentObjectTreeNode::updateMainNodeID($newMainNode->attribute('node_id'), $object->attribute('id'), $object->attribute('current_version'), $newMainNode->attribute('parent_node_id'));
             $this->removeThis();
             eZSearch::addObject($object);
             $db->commit();
         } else {
             // This is the last assignment so we remove the object too
             $db = eZDB::instance();
             $db->begin();
             $this->removeThis();
             if ($moveToTrash) {
                 // saving information about this node in ..trash_node table
                 $trashNode = eZContentObjectTrashNode::createFromNode($this);
                 $db = eZDB::instance();
                 $db->begin();
                 $trashNode->storeToTrash();
                 $db->commit();
                 $object->removeThis();
             } else {
                 $object->purge();
             }
             $db->commit();
         }
     } else {
         $this->removeThis();
         if (count($assignedNodes) > 1) {
             eZSearch::addObject($object);
         }
     }
 }
    /**
     * Deletes the current object, all versions and translations, and corresponding tree nodes from the database
     *
     * Transaction unsafe. If you call several transaction unsafe methods you must enclose
     * the calls within a db transaction; thus within db->begin and db->commit.
     */
    function purge()
    {
        $delID = $this->ID;
        // Who deletes which content should be logged.
        eZAudit::writeAudit( 'content-delete', array( 'Object ID' => $delID, 'Content Name' => $this->attribute( 'name' ),
                                                      'Comment' => 'Purged the current object: eZContentObject::purge()' ) );

        $db = eZDB::instance();

        $db->begin();

        $attrOffset = 0;
        $attrLimit = 20;
        while (
            $contentobjectAttributes = $this->allContentObjectAttributes(
                $delID, true, array( 'limit' => $attrLimit, 'offset' => $attrOffset )
            )
        )
        {
            foreach ( $contentobjectAttributes as $contentobjectAttribute )
            {
                $dataType = $contentobjectAttribute->dataType();
                if ( !$dataType )
                    continue;
                $dataType->deleteStoredObjectAttribute( $contentobjectAttribute );
            }
            $attrOffset += $attrLimit;
        }

        eZInformationCollection::removeContentObject( $delID );

        eZContentObjectTrashNode::purgeForObject( $delID );

        $db->query( "DELETE FROM ezcontentobject_tree
             WHERE contentobject_id='$delID'" );

        $db->query( "DELETE FROM ezcontentobject_attribute
             WHERE contentobject_id='$delID'" );

        $db->query( "DELETE FROM ezcontentobject_version
             WHERE contentobject_id='$delID'" );

        $db->query( "DELETE FROM ezcontentobject_name
             WHERE contentobject_id='$delID'" );

        $db->query( "DELETE FROM ezcobj_state_link WHERE contentobject_id=$delID" );

        $db->query( "DELETE FROM ezcontentobject
             WHERE id='$delID'" );

        $db->query( "DELETE FROM eznode_assignment
             WHERE contentobject_id = '$delID'" );

        $db->query( "DELETE FROM ezuser_role
             WHERE contentobject_id = '$delID'" );

        $db->query( "DELETE FROM ezuser_discountrule
             WHERE contentobject_id = '$delID'" );

        eZContentObject::fixReverseRelations( $delID, 'remove' );

        eZSearch::removeObjectById( $delID );

        // Check if deleted object is in basket/wishlist
        $sql = 'SELECT DISTINCT ezproductcollection_item.productcollection_id
                FROM   ezbasket, ezwishlist, ezproductcollection_item
                WHERE  ( ezproductcollection_item.productcollection_id=ezbasket.productcollection_id OR
                         ezproductcollection_item.productcollection_id=ezwishlist.productcollection_id ) AND
                       ezproductcollection_item.contentobject_id=' . $delID;
        $rows = $db->arrayQuery( $sql );
        if ( count( $rows ) > 0 )
        {
            $countElements = 50;
            $deletedArray = array();
            // Create array of productCollectionID will be removed from ezwishlist and ezproductcollection_item
            foreach ( $rows as $row )
            {
                $deletedArray[] = $row['productcollection_id'];
            }
            // Split $deletedArray into several arrays with $countElements values
            $splitted = array_chunk( $deletedArray, $countElements );
            // Remove eZProductCollectionItem and eZWishList
            foreach ( $splitted as $value )
            {
                eZPersistentObject::removeObject( eZProductCollectionItem::definition(), array( 'productcollection_id' => array( $value, '' ) ) );
                eZPersistentObject::removeObject( eZWishList::definition(), array( 'productcollection_id' => array( $value, '' ) ) );
            }
        }
        $db->query( 'UPDATE ezproductcollection_item
                     SET contentobject_id = 0
                     WHERE  contentobject_id = ' . $delID );

        // Cleanup relations in two steps to avoid locking table for to long
        $db->query( "DELETE FROM ezcontentobject_link
                     WHERE from_contentobject_id = '$delID'" );

        $db->query( "DELETE FROM ezcontentobject_link
                     WHERE to_contentobject_id = '$delID'" );

        // Cleanup properties: LastVisit, Creator, Owner
        $db->query( "DELETE FROM ezuservisit
             WHERE user_id = '$delID'" );

        $db->query( "UPDATE ezcontentobject_version
             SET creator_id = 0
             WHERE creator_id = '$delID'" );

        $db->query( "UPDATE ezcontentobject
             SET owner_id = 0
             WHERE owner_id = '$delID'" );

        if ( isset( $GLOBALS["eZWorkflowTypeObjects"] ) and is_array( $GLOBALS["eZWorkflowTypeObjects"] ) )
        {
            $registeredTypes =& $GLOBALS["eZWorkflowTypeObjects"];
        }
        else
        {
            $registeredTypes = eZWorkflowType::fetchRegisteredTypes();
        }

        // Cleanup ezworkflow_event etc...
        foreach ( array_keys( $registeredTypes ) as $registeredTypeKey )
        {
            $registeredType = $registeredTypes[$registeredTypeKey];
            $registeredType->cleanupAfterRemoving( array( 'DeleteContentObject' => $delID ) );
        }

        $db->commit();
    }