Exemple #1
0
 /**
  * Запуск в работу
  *
  * @param mixed $data данные для задачи
  * @param bool $wait ожидание результата
  *@return mixed результатs
  */
 public function run($data = null, $wait = true)
 {
     // добавляем задачу
     if ($data) {
         $this->add($data);
     }
     // обработка
     while ($this->_Messages->count()) {
         $message = $this->_Messages->pop();
         $this->_Channel->basic_publish($message, '', $this->_queue());
         // массив запущенных задач
         $this->_runtime[$message->get('correlation_id')] = time();
     }
     // если есть обработчик ответов, то слушаем его
     if ($this->_cbQueue && $wait) {
         if (method_exists($this, 'onResponse')) {
             $this->_Channel->basic_consume($this->_cbQueue, '', false, true, false, false, [$this, 'onResponse']);
         } else {
             // если же метода нет, но подождать надо, то тут всё просто:
             $this->_Channel->basic_consume($this->_cbQueue, '', false, true, false, false, function (AMQPMessage $Message) {
                 $response = $this->_decode($Message->body);
                 unset($this->_collerations[$Message->get('correlation_id')], $this->_runtime[$Message->get('correlation_id')]);
                 if ($response instanceof \Exception) {
                     throw $response;
                 }
                 return true;
             });
         }
         // ждём
         while (count($this->_collerations)) {
             $this->_Channel->wait();
         }
     }
     return true;
 }
 public function onExit($status)
 {
     if ($this->pendingRequests->count() > 0) {
         $nextExpectedTest = $this->pendingRequests->dequeue();
         $this->distributor->testCompleted($this, TestResult::errorFromRequest($nextExpectedTest, "Worker{$this->id} died\n{$this->testErr}"));
     }
 }
Exemple #3
0
 /** @return Error|null */
 public static function pop()
 {
     if (!self::$errors) {
         return null;
     }
     return self::$errors->count() > 0 ? self::$errors->dequeue() : null;
 }
Exemple #4
0
 /**
  * Dump promise state, result and number of callbacks.
  * 
  * @return array
  */
 public function __debugInfo() : array
 {
     static $states = [Awaitable::PENDING => 'PENDING', Awaitable::RESOLVED => 'RESOLVED', Awaitable::FAILED => 'FAILED'];
     $info = \get_object_vars($this);
     $info['state'] = $states[$this->state];
     $info['callbacks'] = $this->callbacks ? $this->callbacks->count() : 0;
     \ksort($info);
     return $info;
 }
Exemple #5
0
 /**
  * Starts the event loop.
  */
 public function run()
 {
     $timeout = 0;
     while (!empty($this->future) && !$this->main->isFinished()) {
         $this->waitForStreamActivity($timeout);
         $this->nextTick();
         $timeout = $this->tick->count() === 0 ? 1 : 0;
         $this->tick();
     }
 }
 protected function shouldShutDownMessenger(Messenger $messenger)
 {
     if ($this->callQueue->count() == 0 && $this->pool->count() > $this->options['min_size']) {
         unset($this->coreMessengerMapping[spl_object_hash($messenger)]);
         $this->pool->detach($messenger);
         $messenger->softTerminate();
         return;
     }
     $this->readyPool->enqueue($messenger);
 }
 /**
  * Once a connection has finished being used...
  * @param Connection $connection
  */
 public function releaseConnection(Connection $connection)
 {
     // If we have any promises waiting for the connection, pass it along.
     if ($this->waiting->count() > 0) {
         $cb = $this->waiting->dequeue();
         $cb($connection);
         return;
     }
     // Otherwise, move it to the idle queue.
     $this->available->enqueue($connection);
 }
 /**
  * @param callable $func
  * @return callable
  */
 protected function filesystemResultHandler(callable $func)
 {
     return function ($mixed) use($func) {
         if ($this->callQueue->count() == 0) {
             $this->callQueueActive = false;
         } else {
             $this->processQueue();
         }
         return $func($mixed);
     };
 }
Exemple #9
0
 /**
  * Process the Queue
  *
  * @throws \Exception
  */
 public function processQueue()
 {
     if (!$this->getAllowMultipleRegistrations()) {
         throw new \Exception("Queuing only allowed when there are multiple registrations");
     }
     // find the best candidate
     while ($this->callQueue->count() > 0) {
         $registration = NULL;
         if (strcasecmp($this->getInvokeType(), Registration::FIRST_REGISTRATION) === 0) {
             $registration = $this->getNextFirstRegistration();
         } else {
             if (strcasecmp($this->getInvokeType(), Registration::LAST_REGISTRATION) === 0) {
                 $registration = $this->getNextLastRegistration();
             } else {
                 if (strcasecmp($this->getInvokeType(), Registration::RANDOM_REGISTRATION) === 0) {
                     $registration = $this->getNextRandomRegistration();
                 } else {
                     if (strcasecmp($this->getInvokeType(), Registration::ROUNDROBIN_REGISTRATION) === 0) {
                         $registration = $this->getNextRoundRobinRegistration();
                     } else {
                         if (strcasecmp($this->getInvokeType(), Registration::THRUWAY_REGISTRATION) === 0) {
                             $registration = $this->getNextThruwayRegistration();
                         }
                     }
                 }
             }
         }
         if ($registration === NULL) {
             break;
         }
         $call = $this->callQueue->dequeue();
         $registration->processCall($call);
     }
 }
Exemple #10
0
 /**
  * Process the Queue
  *
  * @throws \Exception
  */
 public function processQueue()
 {
     if (!$this->getAllowMultipleRegistrations()) {
         throw new \Exception("queuing only allowed when there are multiple registrations");
     }
     // find the best candidate
     while ($this->callQueue->count() > 0) {
         $congestion = true;
         /* @var $bestRegistration \Thruway\Registration */
         $bestRegistration = $this->registrations[0];
         /* @var $registration \Thruway\Registration */
         foreach ($this->registrations as $registration) {
             if ($registration->getSession()->getPendingCallCount() == 0) {
                 $bestRegistration = $registration;
                 $congestion = false;
                 break;
             }
             if ($registration->getSession()->getPendingCallCount() < $bestRegistration->getSession()->getPendingCallCount()) {
                 $bestRegistration = $registration;
             }
         }
         if ($congestion) {
             // there is congestion
             $bestRegistration->getSession()->getRealm()->publishMeta('thruway.metaevent.procedure.congestion', [["name" => $this->getProcedureName()]]);
             return;
         }
         $call = $this->callQueue->dequeue();
         $bestRegistration->processCall($call);
     }
 }
Exemple #11
0
function bfs_path($graph, $start, $end)
{
    $queue = new SplQueue();
    # Enqueue the path
    $queue->enqueue([$start]);
    $visited = [$start];
    while ($queue->count() > 0) {
        $path = $queue->dequeue();
        # Get the last node on the path
        # so we can check if we're at the end
        $node = $path[sizeof($path) - 1];
        if ($node === $end) {
            return $path;
        }
        foreach ($graph[$node] as $neighbour) {
            if (!in_array($neighbour, $visited)) {
                $visited[] = $neighbour;
                # Build new path appending the neighbour then and enqueue it
                $new_path = $path;
                $new_path[] = $neighbour;
                $queue->enqueue($new_path);
            }
        }
    }
    return false;
}
Exemple #12
0
 public function processQueue()
 {
     if ($this->commandQueue->count() == 0) {
         return;
     }
     if ($this->connStatus === $this::CONNECTION_BAD) {
         $this->failAllCommandsWith(new \Exception("Bad connection: " . $this->lastError));
         $this->stream->end();
         return;
     }
     while ($this->commandQueue->count() > 0 && $this->queryState === static::STATE_READY) {
         /** @var CommandInterface $c */
         $c = $this->commandQueue->dequeue();
         $this->debug("Sending " . get_class($c));
         if ($c instanceof Query) {
             $this->debug("Sending simple query: " . $c->getQueryString());
         }
         $this->stream->write($c->encodedMessage());
         if ($c instanceof Terminate) {
             $this->stream->end();
         }
         if ($c->shouldWaitForComplete()) {
             $this->queryState = $this::STATE_BUSY;
             if ($c instanceof Query) {
                 $this->queryType = $this::QUERY_SIMPLE;
             } elseif ($c instanceof Sync) {
                 $this->queryType = $this::QUERY_EXTENDED;
             }
             $this->currentCommand = $c;
             return;
         }
     }
 }
 /** @internal */
 private function initReadable()
 {
     $this->readBuffer = new \SplQueue();
     $this->on('__listenersChanged', function () {
         $this->hasDataListeners = 0 != count($this->listeners('data'));
         if (!$this->paused) {
             $this->resume();
         }
     });
     $this->registerPersistentEvents('end', 'error');
     $this->pushFn = function ($object, callable $onFlush = null) : bool {
         if (null === $object) {
             $this->endRead();
             return false;
         }
         $readBufferEmpty = $this->readBuffer->isEmpty();
         if ($this->paused || !$this->hasDataListeners) {
             $this->readBuffer->enqueue([$object, $onFlush]);
             if ($readBufferEmpty) {
                 $this->emit('readable');
             }
         } elseif (!$readBufferEmpty) {
             // not paused but buffer has items - must be within resume()
             $this->readBuffer->enqueue([$object, $onFlush]);
         } else {
             $this->emitData($object, $onFlush);
         }
         return $this->readBuffer->count() < $this->highWaterMark;
     };
 }
Exemple #14
0
 protected function render(Func $func)
 {
     if (null !== $func->cfg) {
         $this->enqueueBlock($func->cfg);
     }
     $renderedOps = new \SplObjectStorage();
     $renderedBlocks = new \SplObjectStorage();
     while ($this->blockQueue->count() > 0) {
         $block = $this->blockQueue->dequeue();
         $ops = [];
         if ($block === $func->cfg) {
             foreach ($func->params as $param) {
                 $renderedOps[$param] = $ops[] = $this->renderOp($param);
             }
         }
         foreach ($block->phi as $phi) {
             $result = $this->indent($this->renderOperand($phi->result) . " = Phi(");
             $result .= implode(', ', array_map([$this, 'renderOperand'], $phi->vars));
             $result .= ')';
             $renderedOps[$phi] = $ops[] = ["op" => $phi, "label" => $result, "childBlocks" => []];
         }
         foreach ($block->children as $child) {
             $renderedOps[$child] = $ops[] = $this->renderOp($child);
         }
         $renderedBlocks[$block] = $ops;
     }
     $varIds = $this->varIds;
     $blockIds = $this->blocks;
     $this->reset();
     return ["blocks" => $renderedBlocks, "ops" => $renderedOps, "varIds" => $varIds, "blockIds" => $blockIds];
 }
 /**
  * Copies for the audits and audits_logs table into the elastic search storage.
  *
  * @return bool
  */
 public function main()
 {
     $table = $this->loadModel('Audits');
     $table->hasMany('AuditDeltas');
     $table->schema()->columnType('created', 'string');
     $map = [];
     $meta = [];
     $featureList = function ($element) {
         list($k, $v) = explode(':', $element);
         (yield $k => $v);
     };
     if (!empty($this->params['type-map'])) {
         $map = explode(',', $this->params['type-map']);
         $map = collection($map)->unfold($featureList)->toArray();
     }
     if (!empty($this->params['extra-meta'])) {
         $meta = explode(',', $this->params['extra-meta']);
         $meta = collection($meta)->unfold($featureList)->toArray();
     }
     $from = (new Time($this->params['from']))->modify('midnight');
     $until = (new Time($this->params['until']))->modify('23:59:59');
     $currentId = null;
     $buffer = new \SplQueue();
     $buffer->setIteratorMode(\SplDoublyLinkedList::IT_MODE_DELETE);
     $queue = new \SplQueue();
     $queue->setIteratorMode(\SplDoublyLinkedList::IT_MODE_DELETE);
     $index = ConnectionManager::get('auditlog_elastic')->getConfig('index');
     $eventsFormatter = function ($audit) use($index, $meta) {
         return $this->eventFormatter($audit, $index, $meta);
     };
     $changesExtractor = [$this, 'changesExtractor'];
     $query = $table->find()->where(function ($exp) use($from, $until) {
         return $exp->between('Audits.created', $from, $until, 'datetime');
     })->where(function ($exp) {
         if (!empty($this->params['exclude-models'])) {
             $exp->notIn('Audits.model', explode(',', $this->params['exclude-models']));
         }
         if (!empty($this->params['models'])) {
             $exp->in('Audits.model', explode(',', $this->params['models']));
         }
         return $exp;
     })->matching('AuditDeltas')->order(['Audits.created', 'AuditDeltas.audit_id'])->bufferResults(false)->hydrate(false)->unfold(function ($audit) use($buffer, &$currentId) {
         if ($currentId && $currentId !== $audit['id']) {
             (yield collection($buffer)->toList());
         }
         $currentId = $audit['id'];
         $buffer->enqueue($audit);
     })->map($changesExtractor)->map($eventsFormatter)->unfold(function ($audit) use($queue) {
         $queue->enqueue($audit);
         if ($queue->count() >= 50) {
             (yield collection($queue)->toList());
         }
     });
     $query->each([$this, 'persistBulk']);
     // There are probably some un-yielded results, let's flush them
     $rest = collection(count($buffer) ? [collection($buffer)->toList()] : [])->map($changesExtractor)->map($eventsFormatter)->append($queue);
     $this->persistBulk($rest->toList());
     return true;
 }
Exemple #16
0
 /**
  * {@inheritDoc}
  */
 public function read()
 {
     $reader = new Awaitable();
     $this->readersQueue->enqueue($reader);
     if ($this->buffer) {
         while (!$this->buffer->isReadable()) {
             (yield $reader->await());
         }
         $this->readersQueue->dequeue();
         $this->notifyAwaiting($this->writersQueue);
         return $this->buffer->read()->content();
     }
     while ($this->messageQueue->count() <= $this->indexOf($reader, $this->readersQueue)) {
         (yield $reader->await());
     }
     $index = $this->indexOf($reader, $this->readersQueue);
     $msg = $this->messageQueue->offsetGet($index);
     $this->readersQueue->offsetUnset($index);
     $this->messageQueue->offsetUnset($index);
     $this->notifyAwaiting($this->readersQueue);
     $this->notifyAwaiting($this->writersQueue);
     return $msg->content();
 }
 /**
  * Write a message to the log.
  *
  * @param  array  $event  log data event
  * @return void
  */
 protected function _write($event)
 {
     if (!$this->flushed) {
         // If we don't reach the flushing priority buffer the event
         if (version_compare($event['priority'], $this->flushPriority, '>')) {
             $this->buffer->enqueue($event);
             // Keep the buffer inside the given limit
             if ($this->limit > 0 && $this->buffer->count() > $this->limit) {
                 $this->buffer->dequeue();
             }
             return;
         }
         // Flush previous log events
         $this->flushed = true;
         foreach ($this->buffer as $evt) {
             $this->writer->write($evt);
         }
     }
     $this->writer->write($event);
 }
Exemple #18
0
 /**
  * This utility function helps removing the COMMENT state from the
  * specified node and their descendants. If the extra attribute is
  * set to false, the compiler does not replace to entities the special
  * symbols. By default, they are entitized.
  *
  * @static
  * @param Opt_Xml_Node $node The starting node.
  * @param boolean $entitize Replace the special symbols to entities?
  */
 public static function removeComments(Opt_Xml_Node $node, $entitize = true)
 {
     // Do not use true recursion.
     $queue = new SplQueue();
     $queue->enqueue($node);
     do {
         $current = $queue->dequeue();
         if ($current instanceof Opt_Xml_Cdata) {
             if ($current->get('commented') === true) {
                 $current->set('commented', false);
             }
             if (!$entitize) {
                 $current->set('noEntitize', true);
             }
         }
         // Add the children of the node to the queue for furhter processing
         foreach ($current as $subnode) {
             $queue->enqueue($subnode);
         }
     } while ($queue->count() > 0);
 }
Exemple #19
0
 /**
  * Send a value through the channel.
  * 
  * @param mixed $value Arbitrary value to be sent.
  * @return mixed Resolves into the value being sent.
  * 
  * @throws ChannelClosedException When the channel has been closed before attempting to send.
  */
 public function send($value) : Awaitable
 {
     if ($this->closed) {
         throw new ChannelClosedException('Cannot send value into a closed channel');
     }
     while ($this->receivers && !$this->receivers->isEmpty()) {
         $receiver = $this->receivers->dequeue();
         if ($receiver->active) {
             $receiver->resolve($value);
             return new Success($value);
         }
     }
     if ($this->buffer && $this->buffer->count() < $this->size) {
         $this->buffer->enqueue($value);
         return new Success($value);
     }
     if (!$this->senders) {
         $this->senders = new \SplQueue();
     }
     $this->senders->enqueue($subscription = new ChannelSubscription($value));
     return $subscription;
 }
Exemple #20
0
 /**
  * Return a path as an array if there's a connected path from $start to $end. false otherwise.
  *
  * @param array   $graph
  * @param integer $start
  * @param integer $end
  * @return array|boolean Path
  */
 function getPath($graph, $start, $end)
 {
     $queue = new \SplQueue();
     $queue->enqueue([$start]);
     $visited = [$start];
     while ($queue->count() > 0) {
         $path = $queue->dequeue();
         $node = $path[sizeof($path) - 1];
         if ($node === $end) {
             return $path;
         }
         foreach ($graph[$node] as $neighbour) {
             if (!in_array($neighbour, $visited)) {
                 $visited[] = $neighbour;
                 $new_path = $path;
                 $new_path[] = $neighbour;
                 $queue->enqueue($new_path);
             }
         }
     }
     return false;
 }
Exemple #21
0
 /**
  * lint a file, pass errors to the queue
  * @param string $file path/to/file
  * @return bool
  */
 private function lintFile($file)
 {
     if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
         $this->output->write('lint file ' . $file . ' ... ');
     }
     $status = false;
     $handler = XMLFileHandler::createXmlHandlerFromFile($file);
     try {
         $handler->getDOMDocument();
         $status = true;
     } catch (XMLHandlerException $e) {
         $msg = new \stdClass();
         if ($handler->hasErrors()) {
             $formatter = new ErrorFormatter($handler->getXmlErrors());
             $formatter->setPrefix('    > ');
             $msg->file = $file;
             $msg->message = $formatter->getErrorsAsString();
         } else {
             $msg->file = $file;
             $msg->message = sprintf('    > %s (Exception: "%s")' . PHP_EOL, $e->getMessage(), get_class($e));
         }
         $this->errorQueue->add($this->errorQueue->count(), $msg);
     }
     if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
         if ($status === false) {
             $this->output->writeln('<error>errors</error>');
         } else {
             $this->output->writeln('<info>passed.</info>');
         }
     } else {
         if ($status === false) {
             $this->output->write('<error>F</error>');
         } else {
             $this->output->write('.');
         }
     }
     return $status;
 }
Exemple #22
0
 /**
  * Sets the new node children queue used in stages 2 and 3 of the compilation.
  *
  * @param SplQueue|Opt_Xml_Scannable $children The children list.
  */
 public function setChildren($children)
 {
     if ($children instanceof SplQueue) {
         if ($children->count() > 0) {
             $this->_newQueue = $children;
         }
     } else {
         if ($children instanceof Opt_Xml_Scannable) {
             if ($children->hasChildren() > 0) {
                 $this->_newQueue = new SplQueue();
                 foreach ($children as $child) {
                     $this->_newQueue->enqueue($child);
                 }
             }
         }
     }
 }
Exemple #23
0
 /**
  * Add page to breadcrumb queue
  *
  * @uses $_[SESSION]
  * @uses session_id()
  * @uses Wakka::GetConfigValue()
  * @uses Config::$num_breadcrumb_nodes
  * @uses Config::$enable_breadcrumbs
  */
 function AddBreadcrumb($page)
 {
     if (0 != $this->GetConfigValue('enable_breadcrumbs')) {
         if (isset($_SESSION['breadcrumbs'])) {
             $q = new SplQueue();
             $q->unserialize($_SESSION['breadcrumbs']);
             if ($page != $q->top()) {
                 while ($q->count() >= $this->GetConfigValue('num_breadcrumb_nodes')) {
                     $q->dequeue();
                 }
                 $q->enqueue($page);
                 $_SESSION['breadcrumbs'] = $q->serialize();
             }
         } else {
             if (isset($_SESSION['user'])) {
                 $q = new SplQueue();
                 $q->enqueue($page);
                 $_SESSION['breadcrumbs'] = $q->serialize();
             }
         }
     }
 }
Exemple #24
0
 public function testBFS()
 {
     $graph = [1 => ['value' => '1', 'data' => ['d1' => 'v1'], 'children' => [2 => ['value' => '2', 'fromParent' => 'd1'], 3 => ['value' => '3', 'children' => [5 => ['value' => '5', 'children' => [7 => ['value' => '7'], 8 => ['value' => '8']]], 6 => ['value' => '6']]], 4 => ['value' => '4']]]];
     $startNode = 1;
     $views = [];
     $visited = array();
     $queue = new \SplQueue();
     $queue->enqueue($graph[$startNode]);
     $visited[] = $startNode;
     while ($queue->count() > 0) {
         $current = $queue->dequeue();
         if (!empty($current['children'])) {
             foreach ($current['children'] as $viewId => $child) {
                 if (!in_array($viewId, $visited)) {
                     $child['parent'] = $current;
                     $queue->enqueue($child);
                 }
                 $visited[] = $viewId;
             }
         }
         $view = ['value' => $current['value']];
         if (isset($current['parent']) && isset($current['fromParent'])) {
             $view['data'][$current['fromParent']] = $current['parent']['data'][$current['fromParent']];
         }
         $views[] = $view;
     }
     $expected = [['value' => '1'], ['value' => '2', 'data' => ['d1' => 'v1']], ['value' => '3'], ['value' => '4'], ['value' => '5'], ['value' => '6'], ['value' => '7'], ['value' => '8']];
     $this->assertEquals($expected, $views);
 }
Exemple #25
0
 /**
  * An utility function that scans the descendants of the component node
  * and looks for special tags. Returns an array of two elements:
  *
  *  - 0 - contains the opt:set XML nodes
  *  - 1 - contains the nodes with the opt:component-attributes attribute
  *
  * @internal
  * @param Opt_Xml_Node $node The starting point
  * @return array
  */
 private function _find($node)
 {
     // We have so many recursions... let's do it in the imperative way.
     $queue = new SplQueue();
     $queue->enqueue($node);
     $result = array(0 => array(), 1 => array());
     $map = array('opt:set' => 0);
     // TODO: Add ignoring the nested components!
     do {
         $current = $queue->dequeue();
         if ($current instanceof Opt_Xml_Element) {
             if (isset($map[$current->getXmlName()])) {
                 $result[$map[$current->getXmlName()]][] = $current;
             } elseif ($current->getNamespace() == 'com' || $current->getAttribute('opt:component-attributes') !== null) {
                 $result[1][] = $current;
             }
         }
         foreach ($current as $subnode) {
             $queue->enqueue($subnode);
         }
     } while ($queue->count() > 0);
     return $result;
 }
 public function info()
 {
     return ['size' => $this->pool->count(), 'queued_calls' => $this->callQueue->count(), 'idle_workers' => $this->readyPool->count()];
 }
Exemple #27
0
 /**
  * Loads the publication into the memory and organizes it into a tree.
  */
 public function loadItems()
 {
     /* HOW DOES IT WORK?
     			
     			All the mystery of the chapter tree sorting algorithm lies in the data organization.
     			The main data structure is a 2-dimensional array, which shows, what the children of the
     			specified node are. So, in the first level, the index is the name of a chapter, and the
     			value is an array of subchapters that are identified by:
     			 - Name
     			 - Order
     
     			In the first stage, we simply load the list of TXT files from the directory. We sort them in
     			order to provide the standard alphanumerical sorting. The structure mentioned above is constructed
     			in the stage 2. We iterate through the filelist and explode each item with a dot. By cutting down the
     			last path element, we are able to specify the parent of the chapter. Now we do two things:
     			 - We create an empty list for the currently processed chapter.
     			 - We add the chapter to its parent children list.
     
     			The stage 3 applies the sorting hints from sort_hints.txt file. We load the file and use basically the
     			same algorithm, as in stage 2, to process its content. So, now we have two lists:
     			 - The first one, sorted alphanumerically
     			 - The second one, that uses the sorting hints.
     
     			In the stage 4, we simply connect them, by scanning the first list. We check, whether it figures in the
     			second one (that means we have to use hints instead of standard sorting). If yes, we copy the order. Once
     			it is completed, we run PHP sort again to apply the order physically.
     
     			Stage 5 creates some meta data for each page, as well as resolves the navigation issue.
     
     			*/
     // The tree structure is always built upon the base language directory content.
     $items = $this->fs->listDirectory('input/' . $this->baseLanguage . '/', true, true);
     // Stage 1
     // See, what are the documentation pages, and what - other files.
     $doc = array();
     foreach ($items as $item) {
         if (($s = strpos($item, '.txt')) !== false) {
             if ($s == strlen($item) - 4) {
                 $doc[] = substr($item, 0, $s);
             }
         } else {
             $this->media[] = $item;
         }
     }
     sort($doc);
     // Stage 2
     // Build the standard connections
     $list = array();
     foreach ($doc as &$item) {
         $extract = explode('.', $item);
         array_pop($extract);
         $parentId = implode('.', $extract);
         if (!isset($list[$parentId])) {
             if ($parentId != '') {
                 echo 'fool';
                 throw new Exception('The parent of "' . $item . '" does not exist.');
             }
             $list[$parentId] = array(0 => array('id' => $item, 'order' => 0));
         } else {
             $list[$parentId][] = array('id' => $item, 'order' => sizeof($list[$parentId]));
         }
         if (!isset($list[$item])) {
             $list[$item] = array();
         }
     }
     try {
         // Stage 3
         // If the hints are not defined, the exception will be thrown and
         // the stages 3 and 4 won't be executed.
         $this->sortHint = $this->fs->readAsArray('sort_hints.txt');
         $sortDuplicates = array_duplicates($this->sortHint);
         if (count($sortDuplicates) > 0) {
             foreach ($sortDuplicates as $duplicate) {
                 $this->prog->console->stdout->writeln('Duplicates of page "' . $duplicate . '" in sort hints.');
             }
             $this->sortHint = array_values(array_unique($this->sortHint));
         }
         $hintedList = array();
         foreach ($this->sortHint as &$item) {
             $extract = explode('.', $item);
             array_pop($extract);
             $parentId = implode('.', $extract);
             $exists = false;
             foreach ($list[$parentId] as &$subitem) {
                 if ($subitem['id'] == $item) {
                     $exists = true;
                     break;
                 }
             }
             if (!$exists) {
                 $this->prog->console->stdout->writeln('Sort hint for "' . $item . '" does not have existing page.');
                 unset($item);
                 continue;
             }
             if (!isset($hintedList[$parentId])) {
                 $hintedList[$parentId] = array($item => array('id' => $item, 'order' => 0));
             } else {
                 $hintedList[$parentId][$item] = array('id' => $item, 'order' => sizeof($hintedList[$parentId]));
             }
         }
         // Stage 4
         foreach ($list as $id => &$item) {
             if (isset($hintedList[$id])) {
                 foreach ($item as &$val) {
                     if (isset($hintedList[$id][$val['id']])) {
                         $val['order'] = $hintedList[$id][$val['id']]['order'];
                     } elseif (strlen($id) == 0) {
                         throw new Exception('Not all base chapters are defined in the sorting hint list. Missing: "' . $val['id'] . '". I don\'t know, what to do.');
                     } else {
                         throw new Exception('Not all children of "' . $id . '" are defined in the sorting hint list. Missing: "' . $val['id'] . '". I don\'t know, what to do.');
                     }
                 }
                 usort($item, array($this, 'orderSort'));
             }
         }
     } catch (SystemException $e) {
         // Nothing to worry, if the file is not accessible. At least the data won't be sorted.
         // TODO: However, if the debug is active, there must be some kind of message.
     }
     /*
      * Part 2 - create the meta-data for each page. (stage 5)
      */
     $this->pages = array();
     $parser = tfParsers::get();
     foreach ($list as $id => &$sublist) {
         foreach ($sublist as $subId => &$item) {
             // Try to load the content: first check the current language
             // if does not exist, load the base language file.
             $metaData = array();
             try {
                 /* If you remove the temporary variable below, you will be killed.
                  * Read the links below and think:
                  *  - http://bugs.php.net/bug.php?id=48408
                  *  - http://bugs.php.net/bug.php?id=48409
                  */
                 $tempVariable = $this->fs->get('input/' . $this->language . '/' . $item['id'] . '.txt');
                 $metaData = $parser->tfdoc($tempVariable);
             } catch (SystemException $e) {
                 $tempVariable = $this->fs->get('input/' . $this->baseLanguage . '/' . $item['id'] . '.txt');
                 $metaData = $parser->tfdoc($tempVariable);
             }
             // Create the additional meta.
             $metaData['Id'] = $item['id'];
             $metaData['Number'] = $item['order'] + 1;
             // Create the navigation according to the chapter layout
             $metaData['_Parent'] = $id;
             $metaData['_Previous'] = null;
             $metaData['_Next'] = null;
             if (isset($sublist[$subId - 1])) {
                 $metaData['_Previous'] = $sublist[$subId - 1]['Id'];
             }
             if (isset($sublist[$subId + 1])) {
                 $metaData['_Next'] = $sublist[$subId + 1]['id'];
             }
             if ($this->config['navigation'] == 'book') {
                 // Create a flat navigation, where "Next" can point to the first child, if accessible
                 $metaData['_XNext'] = $metaData['_Next'];
                 if (isset($this->pages[$metaData['Id']]['_Next'])) {
                     $metaData['_Next'] = $this->pages[$metaData['Id']]['_Next'];
                 }
                 if (!is_null($metaData['_Previous'])) {
                     $xid = $metaData['_Previous'];
                     while (($size = sizeof($list[$xid])) > 0) {
                         $xid = $list[$xid][$size - 1]['id'];
                     }
                     $metaData['_Previous'] = $xid;
                 } elseif (is_null($metaData['_Previous']) && $id != '') {
                     $metaData['_Previous'] = $id;
                 }
                 if (!is_null($metaData['_Previous'])) {
                     $this->pages[$metaData['_Previous']]['_Next'] = $metaData['Id'];
                 }
             }
             $item = $metaData;
             $this->pages[$item['Id']] =& $item;
         }
     }
     // Additional stage that adds the numbers
     $queue = new SplQueue();
     foreach ($list[''] as &$item) {
         $queue->enqueue($item['Id']);
     }
     // Add the numbering.
     $appendixEnum = 'A';
     while ($queue->count() > 0) {
         $id = $queue->dequeue();
         if (isset($this->pages[$id]['Tags']['Appendix']) && $this->pages[$id]['Tags']['Appendix']) {
             $this->pages[$id]['FullNumber'] = $appendixEnum++;
         } else {
             if ($this->pages[$id]['_Parent'] == '') {
                 $this->pages[$id]['FullNumber'] = $this->pages[$id]['Number'];
             } else {
                 $this->pages[$id]['FullNumber'] = $this->pages[$this->pages[$id]['_Parent']]['FullNumber'] . '.' . $this->pages[$id]['Number'];
             }
         }
         foreach ($list[$id] as &$item) {
             $queue->enqueue($item['Id']);
         }
     }
     $this->tree = $list;
 }
Exemple #28
0
 protected final function _getElementsByTagName($name, $ns)
 {
     if (!is_array($this->_subnodes)) {
         return array();
     }
     // Use the queue to avoid recusive calls in this place.
     $queue = new SplQueue();
     foreach ($this->_subnodes as $item) {
         if (is_object($item)) {
             $queue->enqueue($item);
         }
     }
     $result = array();
     while ($queue->count() > 0) {
         $current = $queue->dequeue();
         if ($current instanceof Opt_Xml_Element) {
             if (is_null($ns)) {
                 if ($current->getName() == $name || $name == '*') {
                     $result[] = $current;
                 }
             } else {
                 if (($current->getName() == $name || $name == '*') && ($current->getNamespace() == $ns || $ns == '*')) {
                     $result[] = $current;
                 }
             }
         }
         if ($current instanceof Opt_Xml_Scannable) {
             foreach ($current as $subnode) {
                 $queue->enqueue($subnode);
             }
         }
     }
     return $result;
 }
 /**
  * @return int
  */
 public function count()
 {
     return $this->queue->count();
 }
<?php

$ingredientes = new SplQueue();
$ingredientes->enqueue('Peixe');
$ingredientes->enqueue('Sal');
$ingredientes->enqueue('Limão');
foreach ($ingredientes as $item) {
    print 'Item: ' . $item . '<br>' . PHP_EOL;
}
print PHP_EOL;
print $ingredientes->dequeue() . '<br>' . PHP_EOL;
print 'Count: ' . $ingredientes->count() . '<br>' . PHP_EOL;
print $ingredientes->dequeue() . '<br>' . PHP_EOL;
print 'Count: ' . $ingredientes->count() . '<br>' . PHP_EOL;
print $ingredientes->dequeue() . '<br>' . PHP_EOL;
print 'Count: ' . $ingredientes->count() . '<br>' . PHP_EOL;