// This program is free software; you can redistribute it and/or // modify it under the terms of version 2.0 of the GNU General // Public License as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of version 2.0 of the GNU General // Public License along with this program; if not, write to the Free // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA. // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## // if ( !$isQuiet ) { $cli->output( "Performing cleanup operations." ); $cli->output( "Cleaning up removed items ..." ); } $count = eZFlowOperations::cleanupRemovedItems(); if ( !$isQuiet ) { $cli->output( "Number of removed items: $count" ); $cli->output( "Done." ); } ?>
/** * Do all time based operations on block pool such as rotation, updating * the queue, overflow as well as executes fetch interfaces. * * @static */ public static function update($nodeArray = array()) { // log in user as anonymous if another user is logged in $currentUser = eZUser::currentUser(); if ($currentUser->isLoggedIn()) { $loggedInUser = $currentUser; $anonymousUserId = eZUser::anonymousId(); $anonymousUser = eZUser::instance($anonymousUserId); eZUser::setCurrentlyLoggedInUser($anonymousUser, $anonymousUserId); unset($currentUser, $anonymousUser, $anonymousUserId); } include_once 'kernel/classes/ezcontentcache.php'; $ini = eZINI::instance('block.ini'); $db = eZDB::instance(); // Remove the blocks and items for the block if marked for removal $res = $db->arrayQuery("SELECT id\n FROM ezm_block\n WHERE is_removed=1"); foreach ($res as $row) { $blockID = $row['id']; $db->begin(); $db->query("DELETE FROM ezm_pool\n WHERE block_id='{$blockID}'"); $db->query("DELETE FROM ezm_block\n WHERE id='{$blockID}'"); $db->commit(); } if (!$nodeArray) { // Update pool and pages for all nodes $res = $db->arrayQuery("SELECT DISTINCT node_id FROM ezm_block"); foreach ($res as $row) { $nodeArray[] = $row['node_id']; } } foreach ($nodeArray as $nodeID) { $time = time() - 5; // a safety margin $nodeChanged = false; $blocks = $db->arrayQuery("SELECT *\n FROM ezm_block\n WHERE node_id={$nodeID}"); $blockByID = array(); // Determine the order of updating $correctOrder = array(); $next = array(); foreach ($blocks as $block) { $next[$block['id']] = trim($block['overflow_id']); // Make sure that block ID does not any have spaces $blockByID[$block['id']] = $block; } $nextIDs = array_keys($next); foreach ($nextIDs as $id) { if (in_array($id, $correctOrder, true)) { continue; } if (!$next[$id]) { $correctOrder[] = $id; continue; } $subCorrectOrder = array($id); $currentID = $id; while ($nextID = $next[$currentID]) { if (!in_array($nextID, $nextIDs, true)) { eZDebug::writeWarning("Overflow for {$currentID} is {$nextID}, but no such block was found for the given node", __METHOD__); break; } if (in_array($nextID, $subCorrectOrder, true)) { eZDebug::writeWarning("Loop detected, ignoring ({$nextID} should be after {$currentID} and vice versa)", __METHOD__); break; } if (in_array($nextID, $correctOrder, true)) { break; } $subCorrectOrder[] = $nextID; $currentID = $nextID; } if (!$nextID || !in_array($nextID, $correctOrder, true)) { foreach ($subCorrectOrder as $element) { $correctOrder[] = $element; } } else { $newCorrectOrder = array(); foreach ($correctOrder as $element) { if ($element === $nextID) { foreach ($subCorrectOrder as $element2) { $newCorrectOrder[] = $element2; } } $newCorrectOrder[] = $element; } $correctOrder = $newCorrectOrder; } } // Loop through all block in determined order foreach ($correctOrder as $blockID) { if ($blockByID[$blockID]) { $block = $blockByID[$blockID]; } else { continue; } // Do we need to update block? No, continue to process next block $ttl = 0; if ($ini->hasVariable($block['block_type'], 'TTL')) { $ttl = $ini->variable($block['block_type'], 'TTL'); } if ($ttl + $block['last_update'] >= $time) { continue; } // For "rotating blocks", does the rotation_interval has passed from the last update? if ($block['rotation_type'] != self::ROTATION_NONE && $block['last_update'] + $block['rotation_interval'] >= $time) { continue; } $blockChanged = false; // Fetch new objects and add them to the queue of the current block eZFlowOperations::updateBlockPoolByBlockID($block, $time); $db->begin(); // We need to find out if there are any items to move from the queue $movingFromQueue = $db->arrayQuery("SELECT object_id\n FROM ezm_pool\n WHERE block_id='{$blockID}'\n AND ts_visible=0\n AND ts_hidden=0\n AND ts_publication<={$time}\n ORDER BY ts_publication ASC, priority ASC"); if ($movingFromQueue) { $blockChanged = true; // Find out a number of items in "valid" state and the max. priority used $countMaxPriorityValid = $db->arrayQuery("SELECT count(*) AS count, max(priority) AS priority\n FROM ezm_pool\n WHERE block_id='{$blockID}'\n AND ts_visible>0\n AND ts_hidden=0"); $countValid = $countMaxPriorityValid[0]['count']; $maxPriorityValid = $countMaxPriorityValid[0]['priority']; if ($countValid == 0) { $maxPriorityValid = 0; } $priority = $maxPriorityValid + 1; // Move objects waiting in queue to the "valid ones" foreach ($movingFromQueue as $itemToMove) { $objectID = $itemToMove['object_id']; $db->query("UPDATE ezm_pool\n SET ts_visible={$time}, priority={$priority}\n WHERE block_id='{$blockID}'\n AND object_id={$objectID}"); $priority++; } $countValid += count($movingFromQueue); // Compare this number to the given and archive the oldest (order by ts_visible) $numberOfValidItems = $ini->variable($block['block_type'], 'NumberOfValidItems'); if (!$numberOfValidItems) { $numberOfValidItems = 20; eZDebug::writeWarning('Number of valid items for ' . $block['block_type'] . ' is not set; using the default value (' . $numberOfValidItems . ')', __METHOD__); } $countToRemove = $countValid - $numberOfValidItems; if ($countToRemove > 0) { $overflowID = $block['overflow_id']; $items = $db->arrayQuery("SELECT node_id, object_id, rotation_until\n FROM ezm_pool\n WHERE block_id='{$blockID}'\n AND ts_visible>0\n AND ts_hidden=0\n ORDER BY priority ASC", array('limit' => $countToRemove)); if ($items) { $itemArray = array(); $priority = 0; foreach ($items as $item) { $objectID = $item['object_id']; if ($block['rotation_type'] != self::ROTATION_NONE && ($item['rotation_until'] > $time || $item['rotation_until'] == 0)) { if ($block['rotation_type'] == self::ROTATION_SIMPLE) { // Simple rotation $newPublicationTS = -$time; $priority++; } else { // Random rotation/Shuffle $newPublicationTS = 0; $priority = mt_rand(); } // Move item back to queue $db->query("UPDATE ezm_pool\n SET ts_visible=0,\n ts_publication=-{$time},\n priority={$priority}\n WHERE block_id='{$blockID}'\n AND object_id={$objectID}"); } else { $itemArray[] = $objectID; } } if ($itemArray) { if ($overflowID) { // Put $itemArray items into pool of different block $priority = 0; foreach ($items as $item) { $itemObjectID = $item['object_id']; $itemNodeID = $item['node_id']; // Check if the object_id is not already in the new block $duplicityCheck = $db->arrayQuery("SELECT object_id\n FROM ezm_pool\n WHERE block_id='{$overflowID}'\n AND object_id={$itemObjectID}", array('limit' => 1)); if ($duplicityCheck) { eZDebug::writeNotice("Object {$itemObjectID} is already available in the block {$overflowID}.", __METHOD__); } else { $db->query("INSERT INTO ezm_pool(block_id,object_id,node_id,ts_publication,priority)\n VALUES ('{$overflowID}',{$itemObjectID},{$itemNodeID},{$time},{$priority})"); $priority++; } } $db->query("UPDATE ezm_pool\n SET ts_hidden={$time},\n moved_to='{$overflowID}',\n priority=0\n WHERE block_id='{$blockID}'\n AND " . $db->generateSQLINStatement($itemArray, 'object_id')); } else { $db->query("UPDATE ezm_pool\n SET ts_hidden={$time},\n priority=0\n WHERE block_id='{$blockID}'\n AND " . $db->generateSQLINStatement($itemArray, 'object_id')); } } } } // Cleanup in archived items $countArchived = $db->arrayQuery("SELECT count(*) AS count\n FROM ezm_pool\n WHERE block_id='{$blockID}'\n AND ts_hidden>0"); $countArchived = $countArchived[0]['count']; // Compare this number to the given and remove the oldest ones $numberOfArchivedItems = $ini->variable($block['block_type'], 'NumberOfArchivedItems'); if ($numberOfArchivedItems < 0) { $numberOfArchivedItems = 50; eZDebug::writeWarning('Number of archived items for ' . $block['block_type'] . ' is not set; using the default value (' . $numberOfArchivedItems . ')', __METHOD__); } $countToRemove = $countArchived - $numberOfArchivedItems; if ($countToRemove > 0) { $items = $db->arrayQuery("SELECT object_id\n FROM ezm_pool\n WHERE block_id='{$blockID}'\n AND ts_hidden>0\n ORDER BY ts_hidden ASC", array('limit' => $countToRemove)); if ($items) { $itemArray = array(); foreach ($items as $item) { $itemArray[] = $item['object_id']; } $db->query("DELETE FROM ezm_pool\n WHERE block_id='{$blockID}'\n AND " . $db->generateSQLINStatement($itemArray, 'object_id')); } } } // If the block changed, we need to update whole node if ($blockChanged) { $nodeChanged = true; } $db->commit(); } if ($nodeChanged) { $contentObject = eZContentObject::fetchByNodeID($nodeID); if ($contentObject) { eZContentCacheManager::clearContentCache($contentObject->attribute('id')); } } } // log the previously logged in user if it was changed to anonymous earlier if (isset($loggedInUser)) { eZUser::setCurrentlyLoggedInUser($loggedInUser, $loggedInUser->attribute('contentobject_id')); } }
/** * Performs necessary actions with attribute data after object is published, * it means that you have access to published nodes. * * @param eZContentObjectAttribute $contentObjectAttribute * @param eZContentObject $contentObject * @param array(eZContentObjectTreeNode) $publishedNodes * @return bool */ function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes ) { $db = eZDB::instance(); $page = $contentObjectAttribute->content(); foreach ( $publishedNodes as $publishedNode ) { if ( $publishedNode->isMain() ) $mainNode = $publishedNode; } foreach ( $publishedNodes as $node ) { $nodeID = $node->attribute( 'node_id' ); if ( $page->getZoneCount() != 0 ) { foreach ( $page->attribute( 'zones' ) as $zone ) { if ( $zone->getBlockCount() != 0 ) { if ( $zone->toBeRemoved() ) { foreach ( $zone->attribute( 'blocks' ) as $index => $block ) { $block->setAttribute( 'action', 'remove' ); } } $newItems = array(); foreach ( $zone->attribute( 'blocks' ) as $block ) { $blockID = $block->attribute( 'id' ); $fetchParams = $block->attribute( 'fetch_params' ); $escapedBlockName = $db->escapeString( $block->attribute( 'name' ) ); switch ( $block->attribute( 'action' ) ) { case 'remove': $db->query( "UPDATE ezm_block SET is_removed='1' WHERE id='" . $blockID . "'" ); break; case 'add': $blockCount = $db->arrayQuery( "SELECT COUNT( id ) as count FROM ezm_block WHERE id='" . $blockID ."'" ); if ( $blockCount[0]['count'] == 0 ) { $rotationType = 0; $rotationInterval = 0; $overflowID = null; if ( $block->hasAttribute( 'rotation' ) ) { $rotation = $block->attribute( 'rotation' ); $rotationType = $rotation['type']; $rotationInterval = $rotation['interval']; } if ( $block->hasAttribute( 'overflow_id' ) ) $overflowID = $block->attribute( 'overflow_id' ); $db->query( "INSERT INTO ezm_block ( id, zone_id, name, node_id, overflow_id, block_type, fetch_params, rotation_type, rotation_interval ) VALUES ( '" . $blockID . "', '" . $block->attribute( 'zone_id' ) . "', '" . $escapedBlockName . "', '" . $nodeID . "', '" . $overflowID . "', '" . $db->escapeString( $block->attribute( 'type' ) ) . "', '" . $fetchParams . "', '" . $rotationType . "', '" . $rotationInterval . "' )" ); } break; default: $rotationType = 0; $rotationInterval = 0; $overflowID = null; if ( $block->hasAttribute( 'rotation' ) ) { $rotation = $block->attribute( 'rotation' ); $rotationType = $rotation['type']; $rotationInterval = $rotation['interval']; } if ( $block->hasAttribute( 'overflow_id' ) ) $overflowID = $block->attribute( 'overflow_id' ); // Fixes http://jira.ez.no/browse/EZP-23124 where ezm_block.node_id might be = 0 // due to the way staging handles ezflow // If the block's node id is set to 0, it gets set to the main node ID $blockNodeId = $block->attribute( 'node_id' ) ?: $mainNode->attribute( 'node_id' ); $db->query( "UPDATE ezm_block SET name='" . $escapedBlockName . "', overflow_id='" . $overflowID . "', fetch_params='" . $fetchParams . "', rotation_type='" . $rotationType . "', rotation_interval='" . $rotationInterval ."', node_id='" . $blockNodeId. "' WHERE id='" . $blockID . "'" ); break; } if ( $block->getItemCount() != 0 ) { foreach ( $block->attribute( 'items' ) as $item ) { switch ( $item->attribute( 'action' ) ) { case 'remove': $db->query( "DELETE FROM ezm_pool WHERE object_id='" . $item->attribute( 'object_id' ) . "' AND block_id='" . $blockID . "'" ); break; case 'add': $newItems[] = array( 'blockID' => $blockID, 'objectID' => $item->attribute( 'object_id' ), 'nodeID' => $item->attribute( 'node_id' ), 'priority' => $item->attribute( 'priority' ), 'timestamp' => $item->attribute( 'ts_publication' ), ); break; case 'modify': $updateQuery = array(); if ( $item->hasAttribute( 'ts_publication' ) ) { $updateQuery[] = " ts_publication=" . (int)$item->attribute( 'ts_publication' ); } //make sure to update different node locations of the same object if ( $item->hasAttribute( 'node_id' ) ) { $updateQuery[] = " node_id=" . (int)$item->attribute( 'node_id' ); } if ( $item->hasAttribute( 'priority' ) ) { $updateQuery[] = " priority=" . (int)$item->attribute( 'priority' ); } //if there is ts_hidden and ts_visible, update the two fields. This is the case when add items from history if ( $item->hasAttribute( 'ts_hidden' ) && $item->hasAttribute( 'ts_visible' ) ) { $updateQuery[] = " ts_hidden=" . (int)$item->attribute( 'ts_hidden' ) . ", ts_visible=" . (int)$item->attribute( 'ts_visible' ); } if ( !empty( $updateQuery ) ) { $db->query( "UPDATE ezm_pool SET " . join( ", ", $updateQuery ) . " WHERE object_id=" . (int)$item->attribute( 'object_id' ) . " AND block_id='" . $blockID ."'" ); } break; } } } } if ( !empty( $newItems ) ) { eZFlowPool::insertItems( $newItems ); } } } } } if ( eZFlowOperations::updateOnPublish() ) { $nodeArray = array(); foreach ( $publishedNodes as $node ) { $nodeArray[] = $node->attribute( 'node_id' ); } eZFlowOperations::update( $nodeArray ); } foreach ( $publishedNodes as $node ) { $url = $node->attribute( 'path_identification_string' ); eZURI::transformURI( $url, false, 'full' ); eZHTTPCacheManager::execute( $url ); } $page->removeProcessed(); $contentObjectAttribute->content( $page ); $contentObjectAttribute->store(); return true; }
/** * Performs necessary actions with attribute data after object is published, * it means that you have access to published nodes. * * @param eZContentObjectAttribute $contentObjectAttribute * @param eZContentObject $contentObject * @param array(eZContentObjectTreeNode) $publishedNodes * @return bool */ function onPublish($contentObjectAttribute, $contentObject, $publishedNodes) { $db = eZDB::instance(); $page = $contentObjectAttribute->content(); foreach ($publishedNodes as $node) { $nodeID = $node->attribute('node_id'); if ($page->getZoneCount() != 0) { foreach ($page->attribute('zones') as $zone) { if ($zone->getBlockCount() != 0) { if ($zone->toBeRemoved()) { foreach ($zone->attribute('blocks') as $index => $block) { $block->setAttribute('action', 'remove'); } } foreach ($zone->attribute('blocks') as $block) { $blockID = $block->attribute('id'); $blockType = $block->attribute('type'); $escapedBlockType = $db->escapeString($blockType); $action = $block->attribute('action'); $fetchParams = $block->attribute('fetch_params'); $zoneID = $block->attribute('zone_id'); $blockName = $block->attribute('name'); $escapedBlockName = $db->escapeString($blockName); switch ($action) { case 'remove': $db->query("UPDATE ezm_block SET is_removed='1' WHERE id='" . $blockID . "'"); break; case 'add': $blockCount = $db->arrayQuery("SELECT COUNT( id ) as count FROM ezm_block WHERE id='" . $blockID . "'"); if ($blockCount[0]['count'] == 0) { $rotationType = 0; $rotationInterval = 0; $overflowID = null; if ($block->hasAttribute('rotation')) { $rotation = $block->attribute('rotation'); $rotationType = $rotation['type']; $rotationInterval = $rotation['interval']; } if ($block->hasAttribute('overflow_id')) { $overflowID = $block->attribute('overflow_id'); } $db->query("INSERT INTO ezm_block ( id, zone_id, name, node_id, overflow_id, block_type, fetch_params, rotation_type, rotation_interval )\n VALUES ( '" . $blockID . "',\n '" . $zoneID . "',\n '" . $escapedBlockName . "',\n '" . $nodeID . "',\n '" . $overflowID . "',\n '" . $escapedBlockType . "',\n '" . $fetchParams . "',\n '" . $rotationType . "',\n '" . $rotationInterval . "' )"); } break; default: $rotationType = 0; $rotationInterval = 0; $overflowID = null; if ($block->hasAttribute('rotation')) { $rotation = $block->attribute('rotation'); $rotationType = $rotation['type']; $rotationInterval = $rotation['interval']; } if ($block->hasAttribute('overflow_id')) { $overflowID = $block->attribute('overflow_id'); } $db->query("UPDATE ezm_block SET name='" . $escapedBlockName . "',\n overflow_id='" . $overflowID . "',\n fetch_params='" . $fetchParams . "',\n rotation_type='" . $rotationType . "',\n rotation_interval='" . $rotationInterval . "'\n WHERE id='" . $blockID . "'"); break; } if ($block->getItemCount() != 0) { foreach ($block->attribute('items') as $item) { $action = $item->attribute('action'); switch ($action) { case 'remove': $db->query("DELETE FROM ezm_pool\n WHERE object_id='" . $item->attribute('object_id') . "'\n AND block_id='" . $blockID . "'"); break; case 'add': $itemCount = $db->arrayQuery("SELECT COUNT( * ) as count FROM ezm_pool\n WHERE block_id='" . $blockID . "'\n AND object_id='" . $item->attribute('object_id') . "'"); if ($itemCount[0]['count'] == 0) { $db->query("INSERT INTO ezm_pool ( block_id, object_id, node_id, priority, ts_publication )\n VALUES ( '" . $blockID . "',\n '" . $item->attribute('object_id') . "',\n '" . $item->attribute('node_id') . "',\n '" . $item->attribute('priority') . "',\n '" . $item->attribute('ts_publication') . "' )"); } break; case 'modify': if ($item->hasAttribute('ts_publication')) { $db->query("UPDATE ezm_pool SET ts_publication='" . $item->attribute('ts_publication') . "'\n WHERE object_id='" . $item->attribute('object_id') . "'\n AND block_id='" . $blockID . "'"); } if ($item->hasAttribute('priority')) { $db->query("UPDATE ezm_pool SET priority='" . $item->attribute('priority') . "'\n WHERE object_id='" . $item->attribute('object_id') . "'\n AND block_id='" . $blockID . "'"); } //if there is ts_hidden and ts_visible, update the two fields. This is the case when add items from history if ($item->hasAttribute('ts_hidden') && $item->hasAttribute('ts_visible')) { $db->query("UPDATE ezm_pool SET ts_hidden='" . $item->attribute('ts_hidden') . "',\n ts_visible='" . $item->attribute('ts_visible') . "' \n WHERE object_id='" . $item->attribute('object_id') . "'\n AND block_id='" . $blockID . "'"); } break; } } } } } } } } if (eZFlowOperations::updateOnPublish()) { $nodeArray = array(); foreach ($publishedNodes as $node) { $nodeArray[] = $node->attribute('node_id'); } eZFlowOperations::update($nodeArray); } foreach ($publishedNodes as $node) { $url = $node->attribute('path_identification_string'); eZURI::transformURI($url, false, 'full'); eZHTTPCacheManager::execute($url); } $page->removeProcessed(); $contentObjectAttribute->content($page); $contentObjectAttribute->store(); return true; }
<?php // // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## // SOFTWARE NAME: eZ Flow // SOFTWARE RELEASE: 1.1-0 // COPYRIGHT NOTICE: Copyright (C) 1999-2014 eZ Systems AS // SOFTWARE LICENSE: GNU General Public License v2.0 // NOTICE: > // This program is free software; you can redistribute it and/or // modify it under the terms of version 2.0 of the GNU General // Public License as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of version 2.0 of the GNU General // Public License along with this program; if not, write to the Free // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA. // // // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## // if (!$isQuiet) { $cli->output("Updating ezm_pool"); } eZFlowOperations::update();