/**
  * For event in shared context:
  * Node.@images.add.post
  *
  * @param NodeRef $nodeRef      NodeRef Being Added
  * @param Node    $node         Node Being added
  * @param null    $notUsed      Paramater passed in via Events::trigger, but set to null, and not used.
  * @param bool    $asyncRebuild Wether to rebuildThumbnails asyncronously or not (defaults to true)
  *
  * @return void
  */
 public function processAdd(NodeRef $nodeRef, Node $node, $notUsed = null, $asyncRebuild = true)
 {
     $node = $this->RegulatedNodeService->getByNodeRef($nodeRef, new NodePartials('', '#original.fields'));
     //-----------
     // Build CMS thumbnail separately so that it's ready when this action completes.
     $file = $this->FileService->retrieveFileFromNode($node->getElement(), $node->getOutTag('#original')->TagLinkNodeRef);
     if ($file === null) {
         throw new Exception('File cannot be retrieved for Node');
     }
     $cmsThumb = $this->ImageService->createAndStoreThumbnail($node->getElement(), $this->imagesThumbnailCmsSize, $file->getLocalPath(), $this->ImageService->filenameForNode($node));
     $tag = new Tag($cmsThumb->getElement()->getSlug(), $cmsThumb->Slug, '#thumbnails', $this->imagesThumbnailCmsSize, $this->imagesThumbnailCmsSize);
     $node->replaceOutTags('#thumbnails', array($tag));
     $this->RegulatedNodeService->edit($node);
     if ($asyncRebuild) {
         // commit so the node is ready for the worker
         $this->TransactionManager->commit()->begin();
         //-----------
         // Rebuild thumbnails asynchronously
         $workerParams = array('nodeRef' => '' . $node->getNodeRef(), 'forceRebuildExisting' => false);
         $this->GearmanService->doBackgroundJob('ImagesWorker', 'rebuildThumbnails', $workerParams, 'high');
     } else {
         $this->ImageService->rebuildMissingThumbnails($node->getNodeRef(), false);
     }
     // remove storage facility generated temp file
     @unlink($file->getLocalPath());
 }
 public function buildThumbnails(NodeRef $nodeRef, Node $node)
 {
     // commit so the node is ready for the worker
     $this->TransactionManager->commit()->begin();
     //-----------
     // Rebuild thumbnails asynchronously
     $workerParams = array('nodeRef' => '' . $nodeRef, 'forceRebuildExisting' => false);
     $this->GearmanService->doBackgroundJob('ImagesWorker', 'rebuildThumbnails', $workerParams, 'high');
 }
 /**
  * @param QueuedJobDescriptor $job
  * @param string              $date
  */
 public function scheduleJob(QueuedJobDescriptor $job, $date)
 {
     $this->gearmanService->sendJob('scheduled', 'jobqueueExecute', array($job->ID), strtotime($date));
 }
 public function startJobOnQueue(QueuedJobDescriptor $job)
 {
     $this->gearmanService->jobqueueExecute($job->ID);
 }
 /**
  * populate #thumbnails-json using gearman
  *
  * Parameters:
  *  element: required param to specify element or @aspect
  *  interval: nodes to process per pass; default 100
  *  limit: nodes to process per job: default 5000
  *  offset: node to skip to for the job: default 0
  * @return void
  */
 public function syncJsonThumbnailsDistributed()
 {
     $interval = $this->Request->getParameter('interval') or $interval = 100;
     $interval = intval($interval);
     $limit = $this->Request->getParameter('limit') or $limit = 5000;
     $limit = intval($limit);
     $initialOffset = $this->Request->getParameter('offset') or $initialOffset = 0;
     $initialOffset = intval($initialOffset);
     $elementField = $this->Request->getParameter('element');
     $aspect = $this->Request->getParameter('aspect');
     if (!empty($elementField)) {
         if (strpos($elementField, '@') === 0) {
             $elements = $this->ElementService->findAllWithAspect($elementField);
             if (empty($elements)) {
                 echo "No Elements found for aspect [{$elementField}]\n";
                 return;
             }
         } else {
             $element = $this->ElementService->getBySlug($elementField);
             if (empty($element)) {
                 echo "Element not found for slug [{$elementField}]\n";
                 return;
             }
         }
         $elements = array($elementField);
         $offset = $initialOffset;
     } else {
         if (!empty($aspect)) {
             $elementsForAspect = $this->ElementService->findAllWithAspect($aspect);
             if (empty($elementsForAspect)) {
                 echo "No Elements found for aspect [{$aspect}]\n";
                 return;
             }
             $elements = array();
             foreach ($elementsForAspect as $e) {
                 $elements[] = $e->Slug;
             }
             $offset = 0;
         } else {
             echo "Error - must specify one of element or aspect\n";
             return;
         }
     }
     $elementList = implode(',', $elements);
     echo "\nProcessing elements: {$elementList}\n";
     echo "offset = {$offset}, interval = {$interval}, limit = {$limit}\n";
     if ($offset > 0) {
         echo "\nskipping to {$offset} limit {$limit}\n";
     }
     $count = 0;
     $startTime = time();
     foreach ($elements as $element) {
         echo "\nProcessing element: {$element}\n";
         $nq = new NodeQuery();
         $nq->setParameter('Elements.in', $element);
         $nq->setParameter('Count.only', true);
         $nq->setParameter('Status.all', true);
         $nq->setOrderBy('ActiveDate DESC');
         $totalNodeCount = $this->NodeService->findAll($nq)->getTotalRecords();
         echo "Nodes to process: {$totalNodeCount}\n";
         $countForElement = 0;
         while (true) {
             $nq = new NodeQuery();
             $nq->setParameter('NodeRefs.only', true);
             $nq->setParameter('Elements.in', $element);
             $nq->setOrderBy('ActiveDate DESC');
             $nq->setParameter('Status.all', true);
             $nq->setLimit($interval);
             $nq->setOffset($offset);
             //$nodes = $this->NodeService->findAll($nq, true)->getResults();
             $nodes = $this->NodeService->findAll($nq)->getResults();
             if (empty($nodes)) {
                 echo "\nElement '{$element}' done - {$countForElement} nodes processed\n";
                 break;
             }
             $this->Logger->debug('Processing ' . count($nodes));
             $nodeRefs = array();
             foreach ($nodes as $nodeRef) {
                 $nodeRefs[] = '' . $nodeRef;
                 $count++;
                 $countForElement++;
                 if ($count > $limit) {
                     echo "Limit hit at '{$element}' node {$countForElement}\r";
                     break;
                 }
             }
             echo "Nodes processed - element: {$countForElement}, total: {$count}\r";
             $params = array('nodeRefs' => implode(',', $nodeRefs));
             $this->Logger->debug('Initializing Gearman job: ' . ($count + $initialOffset - 1) . " [{$count}:{$limit}] " . $nodeRef);
             $this->GearmanService->doBackgroundJob('ImagesWorker', 'syncJsonThumbnails', $params, 'low');
             usleep(10000);
             if ($count > $limit) {
                 echo "\nLimit hit in '{$element}' - {$countForElement} nodes processed, {$count} jobs initialized\n";
                 $this->Logger->debug('Limit hit: ' . $count . ' jobs initialized');
                 break;
             }
             $offset = $offset + $interval;
         }
         $offset = 0;
     }
     echo "\n\nDone! {$count} nodes processed\n";
     $endTime = time();
     $t = $endTime - $startTime;
     $minutes = ceil($t / 60);
     echo "Process took {$minutes} minutes to complete\n\n";
 }
 /**
  * Store the temporary-zipped-media nodes as proper media nodes.
  *
  * @throws MediaServiceException
  * @param $params
  * @return
  */
 protected function _storeTemporary($params)
 {
     if (empty($params['NodeRef'])) {
         throw new MediaServiceException('NodeRef must be specified');
     }
     list($element, $slug) = explode(':', $params['NodeRef']);
     $tmpParams = array('ElementSlug' => $element, 'NodeSlug' => $slug);
     // get node with all tags
     $node = $this->getNode($tmpParams, 'all');
     // will spit error if not found
     $nodeTitle = $node->Title;
     $nodeSlug = $node->Slug;
     // if a custom title is specified, override existing title & slug
     if (!empty($params['Title']) && $params['Title'] !== $node->Title) {
         $nodeTitle = $params['Title'];
         $nodeSlug = SlugUtils::createSlug($nodeTitle);
     }
     $nodeRef = new NodeRef($this->ElementService->getBySlug($params['ElementSlug']), $nodeSlug);
     $nodeRef = $this->NodeService->generateUniqueNodeRef($nodeRef, $nodeTitle);
     $params['Slug'] = $nodeRef->getSlug();
     $rawParams = $this->Request->getRawParameters();
     // Clean the param keys removing uid
     foreach ($params as $key => $value) {
         if (preg_match('/^#/', $key)) {
             $nkey = preg_replace('/-uid\\d+$/', '', $key);
             if (strcmp($nkey, $key) == 0) {
                 continue;
             }
             $params[$nkey] = $params[$key];
             $rawParams[$nkey] = $rawParams[$key];
             unset($params[$key]);
             unset($rawParams[$key]);
         }
     }
     foreach (array('In', 'Out') as $dir) {
         // Clean the _partials
         if (!empty($params[$dir . 'Tags_partials'])) {
             $newPartials = array();
             $partials = StringUtils::smartSplit($params[$dir . 'Tags_partials'], ',', '"', '\\"');
             foreach ($partials as $p) {
                 $newPartials[] = preg_replace('/-uid\\d+$/', '', $p);
             }
             $params[$dir . 'Tags_partials'] = implode(',', $newPartials);
             $rawParams[$dir . 'Tags_partials'] = implode(',', $newPartials);
         }
         // Clean the tags
         if (isset($params[$dir . 'Tags']) && is_array($params[$dir . 'Tags'])) {
             foreach ($params[$dir . 'Tags'] as $key => $value) {
                 $nkey = preg_replace('/-uid\\d+$/', '', $key);
                 if (strcmp($nkey, $key) == 0) {
                     continue;
                 }
                 $params[$dir . 'Tags'][$nkey] = $params[$dir . 'Tags'][$key];
                 $rawParams[$dir . 'Tags'][$nkey] = $rawParams[$dir . 'Tags'][$key];
                 unset($params[$dir . 'Tags'][$key]);
                 unset($rawParams[$dir . 'Tags'][$key]);
             }
         }
     }
     // create node
     $newNode = $nodeRef->generateNode();
     $this->NodeMapper->defaultsOnNode($newNode);
     //bind posted params to form backing object
     $this->NodeBinder->bindPersistentFields($newNode, $this->getErrors(), $params, $rawParams);
     $this->NodeBinder->fireAddBindEvents($newNode, $this->getErrors(), $params, $rawParams);
     $this->getErrors()->throwOnError();
     $newNode->Title = $nodeTitle;
     // copy other permanent fields
     $newNode->ActiveDate = $node->ActiveDate;
     $newNode->Status = $node->Status;
     // clone all the file out tags
     $outTags = $node->getOutTags();
     $newOutTags = array();
     foreach ($outTags as $tag) {
         if ($tag->getTagElement() == 'file') {
             $tnode = $this->RegulatedNodeService->getByNodeRef($tag->getTagLinkNode()->getNodeRef(), new NodePartials('#parent-element'));
             $fileNode = $this->cloneFileNode($tnode, $newNode->getElement());
             $newTag = new Tag($fileNode->getNodeRef(), '', $tag->getTagRole(), $tag->getTagValue(), $tag->getTagValueDisplay());
             $newOutTags[] = $newTag;
         } else {
             $newOutTags[] = $tag;
         }
     }
     $newNode->addOutTags($newOutTags);
     // copy all in tags
     $newNode->addInTags($node->getInTags());
     // and add the new node
     $newNode = $this->RegulatedNodeService->add($newNode);
     // then remove the temporary node
     $this->RegulatedNodeService->delete($node->getNodeRef());
     // commit so the node is ready for the worker
     $this->TransactionManager->commit()->begin();
     //-----------
     // Rebuild thumbnails asynchronously
     $workerParams = array('nodeRef' => '' . $newNode->getNodeRef(), 'forceRebuildExisting' => false);
     $this->GearmanService->doBackgroundJob('ImagesWorker', 'rebuildThumbnails', $workerParams, 'high');
     return $this->RegulatedNodeService->getByNodeRef($newNode->getNodeRef(), new NodePartials('all', '#original.#url,#original.#width,#original.#height,#original.#size,#thumbnails=150.#url,#thumbnails=150.#size,#thumbnails=150.#height,#thumbnails=150.#width'));
 }