/**
  * Returns the class signals handler
  *
  * @return ezcSignalCollection
  */
 public static function signals()
 {
     if (self::$signals == null) {
         self::$signals = new ezcSignalCollection();
     }
     return self::$signals;
 }
 /**
  * Sends the published object/version for publishing to the queue
  * Used by the content/publish operation
  * @param int $objectId
  * @param int $version
  *
  * @return array( status => int )
  * @since 4.5
  */
 public static function sendToPublishingQueue($objectId, $version)
 {
     $behaviour = ezpContentPublishingBehaviour::getBehaviour();
     if ($behaviour->disableAsynchronousPublishing) {
         $asyncEnabled = false;
     } else {
         $asyncEnabled = eZINI::instance('content.ini')->variable('PublishingSettings', 'AsynchronousPublishing') == 'enabled';
     }
     $accepted = true;
     if ($asyncEnabled === true) {
         // Filter handlers
         $ini = eZINI::instance('content.ini');
         $filterHandlerClasses = $ini->variable('PublishingSettings', 'AsynchronousPublishingFilters');
         if (count($filterHandlerClasses)) {
             $versionObject = eZContentObjectVersion::fetchVersion($version, $objectId);
             foreach ($filterHandlerClasses as $filterHandlerClass) {
                 if (!class_exists($filterHandlerClass)) {
                     eZDebug::writeError("Unknown asynchronous publishing filter handler class '{$filterHandlerClass}'", __METHOD__);
                     continue;
                 }
                 $handler = new $filterHandlerClass($versionObject);
                 if (!$handler instanceof ezpAsynchronousPublishingFilterInterface) {
                     eZDebug::writeError("Asynchronous publishing filter handler class '{$filterHandlerClass}' does not implement ezpAsynchronousPublishingFilterInterface", __METHOD__);
                     continue;
                 }
                 $accepted = $handler->accept();
                 if (!$accepted) {
                     eZDebugSetting::writeDebug("Object #{$objectId}/{$version} was excluded from asynchronous publishing by {$filterHandlerClass}", __METHOD__);
                     break;
                 }
             }
         }
         unset($filterHandlerClasses, $handler);
     }
     if ($asyncEnabled && $accepted) {
         // if the object is already in the process queue, we move ahead
         // this test should NOT be necessary since http://issues.ez.no/17840 was fixed
         if (ezpContentPublishingQueue::isQueued($objectId, $version)) {
             return array('status' => eZModuleOperationInfo::STATUS_CONTINUE);
         } else {
             ezpContentPublishingQueue::add($objectId, $version);
             return array('status' => eZModuleOperationInfo::STATUS_HALTED, 'redirect_url' => "content/queued/{$objectId}/{$version}");
         }
     } else {
         return array('status' => eZModuleOperationInfo::STATUS_CONTINUE);
     }
 }
 /**
  * Starts the publishing process for the linked version. After publishing,
  * the child process is terminated.
  *
  * @return false|int false if the fork fails, the pid of the child process
  *                   after the fork
  */
 public function publish()
 {
     $contentObjectId = $this->version()->attribute('contentobject_id');
     $contentObjectVersion = $this->version()->attribute('version');
     // $processObject = ezpContentPublishingProcess::fetchByContentObjectVersion( $contentObjectId, $contentObjectVersion );
     $this->setStatus(self::STATUS_WORKING, true, "beginning publishing");
     // prepare the cluster file handler for the fork
     eZClusterFileHandler::preFork();
     $pid = pcntl_fork();
     // force the DB connection closed
     $db = eZDB::instance();
     $db->close();
     $db = null;
     eZDB::setInstance(null);
     // Force the new stack DB connection closed as well
     try {
         $kernel = ezpKernel::instance();
         if ($kernel->hasServiceContainer()) {
             $serviceContainer = $kernel->getServiceContainer();
             $dbHandler = $serviceContainer->get('ezpublish.connection');
             $factory = $serviceContainer->get('ezpublish.api.storage_engine.legacy.dbhandler.factory');
             $dbHandler->setDbHandler($factory->buildLegacyDbHandler()->getDbHandler());
         }
     } catch (LogicException $e) {
         // we just ignore this, since it means that we are running in a pure legacy context
     }
     // Force the cluster DB connection closed if the cluster handler is DB based
     $cluster = eZClusterFileHandler::instance();
     // error, cancel
     if ($pid == -1) {
         $this->setStatus(self::STATUS_PENDING, true, "pcntl_fork() failed");
         return false;
     } else {
         if ($pid) {
             return $pid;
         }
     }
     // child process
     try {
         $myPid = getmypid();
         pcntl_signal(SIGCHLD, SIG_IGN);
         $this->setAttribute('pid', $myPid);
         $this->setAttribute('started', time());
         $this->store(array('pid', 'started'));
         // login the version's creator to make sure publishing happens as if ran synchronously
         $creatorId = $this->version()->attribute('creator_id');
         $creator = eZUser::fetch($creatorId);
         eZUser::setCurrentlyLoggedInUser($creator, $creatorId);
         unset($creator, $creatorId);
         $operationResult = eZOperationHandler::execute('content', 'publish', array('object_id' => $contentObjectId, 'version' => $contentObjectVersion));
         // Statuses other than CONTINUE require special handling
         if ($operationResult['status'] != eZModuleOperationInfo::STATUS_CONTINUE) {
             if ($operationResult['status'] == eZModuleOperationInfo::STATUS_HALTED) {
                 // deferred to crontab
                 if (strpos($operationResult['result']['content'], 'Deffered to cron') !== false) {
                     $processStatus = self::STATUS_DEFERRED;
                 } else {
                     $processStatus = self::STATUS_UNKNOWN;
                 }
             } else {
                 $processStatus = self::STATUS_UNKNOWN;
             }
         } else {
             $processStatus = self::STATUS_FINISHED;
         }
         // mark the process as completed
         $this->setAttribute('pid', 0);
         $this->setStatus($processStatus, false, "publishing operation finished");
         $this->setAttribute('finished', time());
         $this->store(array('status', 'finished', 'pid'));
         // Call the postProcessing hook
         ezpContentPublishingQueue::signals()->emit('postHandling', $contentObjectId, $contentObjectVersion, $processStatus);
     } catch (eZDBException $e) {
         $this->reset("database error: " . $e->getMessage());
     }
     // generate static cache
     $ini = eZINI::instance();
     if ($ini->variable('ContentSettings', 'StaticCache') == 'enabled') {
         $staticCacheHandlerClassName = $ini->variable('ContentSettings', 'StaticCacheHandler');
         $staticCacheHandlerClassName::executeActions();
     }
     eZScript::instance()->shutdown();
     exit;
 }
 /**
  * Starts the publishing process for the linked version. After publishing,
  * the child process is terminated.
  *
  * @return false|int false if the fork fails, the pid of the child process
  *                   after the fork
  */
 public function publish()
 {
     $contentObjectId = $this->version()->attribute('contentobject_id');
     $contentObjectVersion = $this->version()->attribute('version');
     // $processObject = ezpContentPublishingProcess::fetchByContentObjectVersion( $contentObjectId, $contentObjectVersion );
     $this->setAttribute('status', self::STATUS_WORKING);
     $this->store(array('status'));
     // prepare the cluster file handler for the fork
     eZClusterFileHandler::preFork();
     $pid = pcntl_fork();
     // force the DB connection closed
     $db = eZDB::instance();
     $db->close();
     $db = null;
     eZDB::setInstance(null);
     // Force the cluster DB connection closed if the cluster handler is DB based
     $cluster = eZClusterFileHandler::instance();
     // error, cancel
     if ($pid == -1) {
         $this->setAttribute('status', self::STATUS_PENDING);
         $this->store(array('status'));
         return false;
     } else {
         if ($pid) {
             return $pid;
         }
     }
     // child process
     try {
         $myPid = getmypid();
         pcntl_signal(SIGCHLD, SIG_IGN);
         $this->setAttribute('pid', $myPid);
         $this->setAttribute('started', time());
         $this->store(array('pid', 'started'));
         // login the version's creator to make sure publishing happens as if ran synchronously
         $creatorId = $this->version()->attribute('creator_id');
         $creator = eZUser::fetch($creatorId);
         eZUser::setCurrentlyLoggedInUser($creator, $creatorId);
         unset($creator, $creatorId);
         $operationResult = eZOperationHandler::execute('content', 'publish', array('object_id' => $contentObjectId, 'version' => $contentObjectVersion));
         // Statuses other than CONTINUE require special handling
         if ($operationResult['status'] != eZModuleOperationInfo::STATUS_CONTINUE) {
             if ($operationResult['status'] == eZModuleOperationInfo::STATUS_HALTED) {
                 // deferred to crontab
                 if (strpos($operationResult['result']['content'], 'Deffered to cron') !== false) {
                     $processStatus = self::STATUS_DEFERRED;
                 } else {
                     $processStatus = self::STATUS_UNKNOWN;
                 }
             } else {
                 $processStatus = self::STATUS_UNKNOWN;
             }
         } else {
             $processStatus = self::STATUS_FINISHED;
         }
         // mark the process as completed
         $this->setAttribute('pid', 0);
         $this->setAttribute('status', $processStatus);
         $this->setAttribute('finished', time());
         $this->store(array('status', 'finished', 'pid'));
         // Call the postProcessing hook
         ezpContentPublishingQueue::signals()->emit('postHandling', $contentObjectId, $contentObjectVersion, $processStatus);
     } catch (eZDBException $e) {
         $this->reset();
     }
     eZScript::instance()->shutdown();
     exit;
 }
 /**
  * InitHooks being "final", we work around it by way of a new function
  */
 public static function init()
 {
     parent::init();
     self::initExtraHooks();
 }