Phalcon Framework 3.4.1

MongoDB\Driver\Exception\ConnectionTimeoutException: No suitable servers found (`serverSelectionTryOnce` set): [connection refused calling ismaster on '127.0.0.1:27017']

/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Collection.php (452)
#0MongoDB\Driver\Manager->selectServer(Object(MongoDB\Driver\ReadPreference))
/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Collection.php (452)
<?php
 
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2016 Phalcon Team (https://www.phalconphp.com)      |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file LICENSE.txt.                             |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to license@phalconphp.com so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: Ben Casey <bcasey@tigerstrikemedia.com>                       |
  +------------------------------------------------------------------------+
*/
 
namespace Phalcon\Db\Adapter\MongoDB;
 
use Traversable;
use MongoDB\Driver\Cursor;
use MongoDB\Driver\Manager;
use MongoDB\Driver\ReadConcern;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\WriteConcern;
use Phalcon\Db\Adapter\MongoDB\Model;
use Phalcon\Db\Adapter\MongoDB\Operation;
use Phalcon\Db\Adapter\MongoDB\Exception\InvalidArgumentException;
 
/**
 * Phalcon\Db\Adapter\MongoDB\Collection
 *
 * @package Phalcon\Db\Adapter\MongoDB
 */
class Collection
{
    private static $defaultTypeMap = [
        'array'    => Model\BSONArray::class,
        'document' => Model\BSONDocument::class,
        'root'     => Model\BSONDocument::class,
    ];
 
    private static $wireVersionForFindAndModifyWriteConcern = 4;
 
    private $collectionName;
    private $databaseName;
    private $manager;
    private $readConcern;
    private $readPreference;
    private $typeMap;
    private $writeConcern;
 
    /**
     * Constructs new Collection instance.
     *
     * This class provides methods for collection-specific operations, such as
     * CRUD (i.e. create, read, update, and delete) and index management.
     *
     * Supported options:
     *
     *  * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
     *    use for collection operations. Defaults to the Manager's read concern.
     *
     *  * readPreference (MongoDB\Driver\ReadPreference): The default read
     *    preference to use for collection operations. Defaults to the Manager's
     *    read preference.
     *
     *  * typeMap (array): Default type map for cursors and BSON documents.
     *
     *  * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
     *    to use for collection operations. Defaults to the Manager's write
     *    concern.
     *
     * @param Manager $manager Manager instance from the driver
     * @param string  $databaseName Database name
     * @param string  $collectionName Collection name
     * @param array   $options Collection options
     *
     * @throws InvalidArgumentException
     */
    public function __construct(Manager $manager, $databaseName, $collectionName, array $options = [])
    {
        if (strlen($databaseName)<1) {
            throw new InvalidArgumentException('$databaseName is invalid: '.$databaseName);
        }
 
        if (strlen($collectionName)<1) {
            throw new InvalidArgumentException('$collectionName is invalid: '.$collectionName);
        }
 
        if (isset($options['readConcern'])&&!$options['readConcern'] instanceof ReadConcern) {
            throw InvalidArgumentException::invalidType(
                '"readConcern" option',
                $options['readConcern'],
                'MongoDB\Driver\ReadConcern'
            );
        }
 
        if (isset($options['readPreference'])&&!$options['readPreference'] instanceof ReadPreference) {
            throw InvalidArgumentException::invalidType(
                '"readPreference" option',
                $options['readPreference'],
                'MongoDB\Driver\ReadPreference'
            );
        }
 
        if (isset($options['typeMap'])&&!is_array($options['typeMap'])) {
            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
        }
 
        if (isset($options['writeConcern'])&&!$options['writeConcern'] instanceof WriteConcern) {
            throw InvalidArgumentException::invalidType(
                '"writeConcern" option',
                $options['writeConcern'],
                'MongoDB\Driver\WriteConcern'
            );
        }
 
        $this->manager       =$manager;
        $this->databaseName  =(string)$databaseName;
        $this->collectionName=(string)$collectionName;
        $this->readConcern   =isset($options['readConcern'])?$options['readConcern']:$this->manager->getReadConcern();
        $this->readPreference=isset($options['readPreference'])
            ?$options['readPreference']
            :$this->manager->getReadPreference();
        $this->typeMap       =isset($options['typeMap'])?$options['typeMap']:self::$defaultTypeMap;
        $this->writeConcern  =isset($options['writeConcern'])
            ?$options['writeConcern']
            :$this->manager->getWriteConcern();
    }
 
    /**
     * Return internal properties for debugging purposes.
     *
     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
     * @return array
     */
    public function __debugInfo()
    {
        return [
            'collectionName'=>$this->collectionName,
            'databaseName'  =>$this->databaseName,
            'manager'       =>$this->manager,
            'readConcern'   =>$this->readConcern,
            'readPreference'=>$this->readPreference,
            'typeMap'       =>$this->typeMap,
            'writeConcern'  =>$this->writeConcern,
        ];
    }
 
    /**
     * Return the collection namespace (e.g. "db.collection").
     *
     * @see https://docs.mongodb.org/manual/faq/developers/#faq-dev-namespace
     * @return string
     */
    public function __toString()
    {
        return $this->databaseName.'.'.$this->collectionName;
    }
 
    /**
     * Executes an aggregation framework pipeline on the collection.
     *
     * Note: this method's return value depends on the MongoDB server version
     * and the "useCursor" option. If "useCursor" is true, a Cursor will be
     * returned; otherwise, an ArrayIterator is returned, which wraps the
     * "result" array from the command response document.
     *
     * Note: BSON deserialization of inline aggregation results (i.e. not using
     * a command cursor) does not yet support a custom type map
     * (depends on: https://jira.mongodb.org/browse/PHPC-314).
     *
     * @param array $pipeline List of pipeline operations
     * @param array $options Command options
     *
     * @return Traversable
     */
    public function aggregate(array $pipeline, array $options = [])
    {
        $hasOutStage=Functions::isLastPipelineOperatorOut($pipeline);
 
        /**
         * A "majority" read concern is not compatible with the $out stage, so
         * avoid providing the Collection's read concern if it would conflict.
         */
        if (!isset($options['readConcern'])&&!($hasOutStage&&$this->readConcern->getLevel()===ReadConcern::MAJORITY)) {
            $options['readConcern']=$this->readConcern;
        }
 
        if (!isset($options['readPreference'])) {
            $options['readPreference']=$this->readPreference;
        }
 
        if ($hasOutStage) {
            $options['readPreference']=new ReadPreference(ReadPreference::RP_PRIMARY);
        }
 
        if (!isset($options['typeMap'])&&(!isset($options['useCursor'])||$options['useCursor'])) {
            $options['typeMap']=$this->typeMap;
        }
 
        $operation = new Operation\Aggregate($this->databaseName, $this->collectionName, $pipeline, $options);
        $server    = $this->manager->selectServer($options['readPreference']);
 
        return $operation->execute($server);
    }
 
    /**
     * Executes multiple write operations.
     *
     * @param array[] $operations List of write operations
     * @param array   $options Command options
     *
     * @return BulkWriteResult
     */
    public function bulkWrite(array $operations, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern']=$this->writeConcern;
        }
 
        $operation=new Operation\BulkWrite($this->databaseName, $this->collectionName, $operations, $options);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Gets the number of documents matching the filter.
     *
     * @param array|object $filter Query by which to filter documents
     * @param array        $options Command options
     *
     * @return integer
     */
    public function count($filter = [], array $options = [])
    {
        if (!isset($options['readConcern'])) {
            $options['readConcern']=$this->readConcern;
        }
 
        if (!isset($options['readPreference'])) {
            $options['readPreference']=$this->readPreference;
        }
 
        $operation=new Operation\Count($this->databaseName, $this->collectionName, $filter, $options);
        $server   =$this->manager->selectServer($options['readPreference']);
 
        return $operation->execute($server);
    }
 
    /**
     * Create a single index for the collection.
     *
     * @param array|object $key Document containing fields mapped to values,
     *                              which denote order or an index type
     * @param array        $options Index options
     *
     * @return string The name of the created index
     */
    public function createIndex($key, array $options = [])
    {
        return current($this->createIndexes([['key'=>$key]+$options]));
    }
 
    /**
     * Create one or more indexes for the collection.
     *
     * Each element in the $indexes array must have a "key" document, which
     * contains fields mapped to an order or type. Other options may follow.
     * For example:
     *
     *     $indexes = [
     *         // Create a unique index on the "username" field
     *         [ 'key' => [ 'username' => 1 ], 'unique' => true ],
     *         // Create a 2dsphere index on the "loc" field with a custom name
     *         [ 'key' => [ 'loc' => '2dsphere' ], 'name' => 'geo' ],
     *     ];
     *
     * If the "name" option is unspecified, a name will be generated from the
     * "key" document.
     *
     * @param array[] $indexes List of index specifications
     *
     * @return string[] The names of the created indexes
     * @throws InvalidArgumentException if an index specification is invalid
     */
    public function createIndexes(array $indexes)
    {
        $operation=new Operation\CreateIndexes($this->databaseName, $this->collectionName, $indexes);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Deletes all documents matching the filter.
     *
     * @param array|object $filter Query by which to delete documents
     * @param array        $options Command options
     *
     * @return DeleteResult
     */
    public function deleteMany($filter, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern']=$this->writeConcern;
        }
 
        $operation=new Operation\DeleteMany($this->databaseName, $this->collectionName, $filter, $options);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Deletes at most one document matching the filter.
     *
     * @param array|object $filter Query by which to delete documents
     * @param array        $options Command options
     *
     * @return DeleteResult
     */
    public function deleteOne($filter, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern']=$this->writeConcern;
        }
 
        $operation=new Operation\DeleteOne($this->databaseName, $this->collectionName, $filter, $options);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Finds the distinct values for a specified field across the collection.
     *
     * @param string       $fieldName Field for which to return distinct values
     * @param array|object $filter Query by which to filter documents
     * @param array        $options Command options
     *
     * @return mixed[]
     */
    public function distinct($fieldName, $filter = [], array $options = [])
    {
        if (!isset($options['readConcern'])) {
            $options['readConcern']=$this->readConcern;
        }
 
        if (!isset($options['readPreference'])) {
            $options['readPreference']=$this->readPreference;
        }
 
        $operation=new Operation\Distinct($this->databaseName, $this->collectionName, $fieldName, $filter, $options);
        $server   =$this->manager->selectServer($options['readPreference']);
 
        return $operation->execute($server);
    }
 
    /**
     * Drop this collection.
     *
     * @param array $options Additional options
     *
     * @return array|object Command result document
     */
    public function drop(array $options = [])
    {
        if (!isset($options['typeMap'])) {
            $options['typeMap']=$this->typeMap;
        }
 
        $operation=new Operation\DropCollection($this->databaseName, $this->collectionName, $options);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Drop a single index in the collection.
     *
     * @param string $indexName Index name
     * @param array  $options Additional options
     *
     * @return array|object Command result document
     * @throws InvalidArgumentException if $indexName is an empty string or "*"
     */
    public function dropIndex($indexName, array $options = [])
    {
        $indexName=(string)$indexName;
 
        if ($indexName==='*') {
            throw new InvalidArgumentException('dropIndexes() must be used to drop multiple indexes');
        }
 
        if (!isset($options['typeMap'])) {
            $options['typeMap']=$this->typeMap;
        }
 
        $operation=new Operation\DropIndexes($this->databaseName, $this->collectionName, $indexName, $options);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Drop all indexes in the collection.
     *
     * @param array $options Additional options
     *
     * @return array|object Command result document
     */
    public function dropIndexes(array $options = [])
    {
        if (!isset($options['typeMap'])) {
            $options['typeMap']=$this->typeMap;
        }
 
        $operation=new Operation\DropIndexes($this->databaseName, $this->collectionName, '*', $options);
        $server   =$this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Finds documents matching the query.
     *
     * @param array|object $filter Query by which to filter documents
     * @param array        $options Additional options
     *
     * @return Cursor
     */
    public function find($filter = [], array $options = [])
    {
        if (!isset($options['readConcern'])) {
            $options['readConcern']=$this->readConcern;
        }
 
        if (!isset($options['readPreference'])) {
            $options['readPreference']=$this->readPreference;
        }
 
        if (!isset($options['typeMap'])) {
            $options['typeMap']=$this->typeMap;
        }
 
        $operation=new Operation\Find($this->databaseName, $this->collectionName, $filter, $options);
        $server   =$this->manager->selectServer($options['readPreference']);
 
        return $operation->execute($server);
    }
 
    /**
     * Finds a single document matching the query.
     *
     * @param array|object $filter Query by which to filter documents
     * @param array        $options Additional options
     *
     * @return array|object|null
     */
    public function findOne($filter = [], array $options = [])
    {
        if (!isset($options['readConcern'])) {
            $options['readConcern']=$this->readConcern;
        }
 
        if (!isset($options['readPreference'])) {
            $options['readPreference']=$this->readPreference;
        }
 
        if (!isset($options['typeMap'])) {
            $options['typeMap']=$this->typeMap;
        }
 
        $operation=new Operation\FindOne($this->databaseName, $this->collectionName, $filter, $options);
        $server   =$this->manager->selectServer($options['readPreference']);
 
        return $operation->execute($server);
    }
 
    /**
     * Finds a single document and deletes it, returning the original.
     *
     * The document to return may be null if no document matched the filter.
     *
     * Note: BSON deserialization of the returned document does not yet support
     * a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
     *
     * @param  array|object $filter  Query by which to filter documents
     * @param  array        $options Command options [Optional]
     * @return object|null
     */
    public function findOneAndDelete($filter, array $options = [])
    {
        $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        if (!isset($options['writeConcern']) && Functions::serverSupportsFeature(
            $server,
            self::$wireVersionForFindAndModifyWriteConcern
        )
        ) {
            $options['writeConcern']=$this->writeConcern;
        }
 
        $operation = new Operation\FindOneAndDelete($this->databaseName, $this->collectionName, $filter, $options);
 
        return $operation->execute($server);
    }
 
    /**
     * Finds a single document and replaces it, returning either the original or
     * the replaced document.
     *
     * The document to return may be null if no document matched the filter. By
     * default, the original document is returned. Specify
     * FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option
     * to return the updated document.
     *
     * Note: BSON deserialization of the returned document does not yet support
     * a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
     *
     * @param  array|object $filter      Query by which to filter documents
     * @param  array|object $replacement Replacement document
     * @param  array        $options     Command options [Optional]
     * @return object|null
     */
    public function findOneAndReplace($filter, $replacement, array $options = [])
    {
        $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        if (!isset($options['writeConcern']) && Functions::serverSupportsFeature(
            $server,
            self::$wireVersionForFindAndModifyWriteConcern
        )
        ) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\FindOneAndReplace(
            $this->databaseName,
            $this->collectionName,
            $filter,
            $replacement,
            $options
        );
 
        return $operation->execute($server);
    }
 
    /**
     * Finds a single document and updates it, returning either the original or
     * the updated document.
     *
     * The document to return may be null if no document matched the filter. By
     * default, the original document is returned. Specify
     * FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option
     * to return the updated document.
     *
     * Note: BSON deserialization of the returned document does not yet support
     * a custom type map (depends on: https://jira.mongodb.org/browse/PHPC-314).
     *
     * @param  array|object $filter  Query by which to filter documents
     * @param  array|object $update  Update to apply to the matched document
     * @param  array        $options Command options [Optional]
     * @return object|null
     */
    public function findOneAndUpdate($filter, $update, array $options = [])
    {
        $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        if (!isset($options['writeConcern']) && Functions::serverSupportsFeature(
            $server,
            self::$wireVersionForFindAndModifyWriteConcern
        )
        ) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\FindOneAndUpdate(
            $this->databaseName,
            $this->collectionName,
            $filter,
            $update,
            $options
        );
 
        return $operation->execute($server);
    }
 
    /**
     * Return the collection name.
     *
     * @return string
     */
    public function getCollectionName()
    {
        return $this->collectionName;
    }
 
    /**
     * Return the database name.
     *
     * @return string
     */
    public function getDatabaseName()
    {
        return $this->databaseName;
    }
 
    /**
     * Return the collection namespace.
     *
     * @return string
     */
    public function getNamespace()
    {
        return $this->databaseName . '.' . $this->collectionName;
    }
 
    /**
     * Inserts multiple documents.
     *
     * @param  array[]|object[] $documents The documents to insert
     * @param  array            $options   Command options [Optional]
     * @return InsertManyResult
     */
    public function insertMany(array $documents, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\InsertMany($this->databaseName, $this->collectionName, $documents, $options);
        $server    = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Inserts one document.
     *
     * @param array|object $document The document to insert
     * @param array        $options  Command options [Optional]
     * @return InsertOneResult
     */
    public function insertOne($document, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\InsertOne($this->databaseName, $this->collectionName, $document, $options);
        $server    = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Inserts the document.
     *
     * @param  array|object $document The document to insert
     * @param  array        $options  Command options [Optional]
     * @return mixed
     */
    public function insert($document, array $options = [])
    {
        return $this->insertOne($document, $options);
    }
 
    /**
     * Returns information for all indexes for the collection.
     *
     * @param  array $options Command options [Optional]
     * @return Model\IndexInfoIterator
     */
    public function listIndexes(array $options = [])
    {
        $operation = new Operation\ListIndexes($this->databaseName, $this->collectionName, $options);
        $server    = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Replaces at most one document matching the filter.
     *
     * @param  array|object $filter      Query by which to filter documents
     * @param  array|object $replacement Replacement document
     * @param  array        $options     Command options [Optional]
     * @return UpdateResult
     */
    public function replaceOne($filter, $replacement, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\ReplaceOne(
            $this->databaseName,
            $this->collectionName,
            $filter,
            $replacement,
            $options
        );
 
        $server = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Updates all documents matching the filter.
     *
     * @param  array|object $filter  Query by which to filter documents
     * @param  array|object $update  Update to apply to the matched documents
     * @param  array        $options Command options [Optional]
     * @return UpdateResult
     */
    public function updateMany($filter, $update, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\UpdateMany($this->databaseName, $this->collectionName, $filter, $update, $options);
        $server    = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Updates at most one document matching the filter.
     *
     * @param  array|object $filter  Query by which to filter documents
     * @param  array|object $update  Update to apply to the matched document
     * @param  array        $options Command options [Optional]
     * @return UpdateResult
     */
    public function updateOne($filter, $update, array $options = [])
    {
        if (!isset($options['writeConcern'])) {
            $options['writeConcern'] = $this->writeConcern;
        }
 
        $operation = new Operation\UpdateOne($this->databaseName, $this->collectionName, $filter, $update, $options);
        $server    = $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
 
        return $operation->execute($server);
    }
 
    /**
     * Get a clone of this collection with different options.
     *
     * @param  array $options Collection constructor options [Optional]
     * @return Collection
     */
    public function withOptions(array $options = [])
    {
        $options += [
            'readConcern'    => $this->readConcern,
            'readPreference' => $this->readPreference,
            'typeMap'        => $this->typeMap,
            'writeConcern'   => $this->writeConcern,
        ];
 
        return new Collection($this->manager, $this->databaseName, $this->collectionName, $options);
    }
}
#1Phalcon\Db\Adapter\MongoDB\Collection->find(Array([ip] => 34.204.11.236), Array([readConcern] => Object(MongoDB\Driver\ReadConcern), [readPreference] => Object(MongoDB\Driver\ReadPreference), [typeMap] => Array([array] => Phalcon\Db\Adapter\MongoDB\Model\BSONArray, [document] => Phalcon\Db\Adapter\MongoDB\Model\BSONDocument, [root] => Phalcon\Db\Adapter\MongoDB\Model\BSONDocument)))
/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Mvc/MongoCollection.php (307)
<?php
 
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2016 Phalcon Team (https://www.phalconphp.com)      |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file LICENSE.txt.                             |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to license@phalconphp.com so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: Ben Casey <bcasey@tigerstrikemedia.com>                       |
  +------------------------------------------------------------------------+
*/
 
namespace Phalcon\Mvc;
 
use Phalcon\Di;
use MongoDB\BSON\ObjectID;
use MongoDB\Driver\WriteConcern;
use MongoDB\BSON\Unserializable;
use Phalcon\Mvc\Collection\Document;
use Phalcon\Mvc\Collection\Exception;
use Phalcon\Mvc\Collection\ManagerInterface;
use Phalcon\Db\Adapter\MongoDB\InsertOneResult;
use Phalcon\Mvc\Collection as PhalconCollection;
use Phalcon\Db\Adapter\MongoDB\Collection as AdapterCollection;
 
/**
 * Class MongoCollection
 *
 * @property ManagerInterface _modelsManager
 * @package Phalcon\Mvc
 */
abstract class MongoCollection extends PhalconCollection implements Unserializable
{
    // @codingStandardsIgnoreStart
    static protected $_disableEvents;
    // @codingStandardsIgnoreEnd
 
    /**
     * {@inheritdoc}
     *
     * @param mixed $id
     */
    public function setId($id)
    {
        if (is_object($id)) {
            $this->_id = $id;
            return;
        }
 
        if ($this->_modelsManager->isUsingImplicitObjectIds($this)) {
            $this->_id = new ObjectID($id);
            return;
        }
 
        $this->_id = $id;
    }
 
    /**
     * {@inheritdoc}
     *
     * @return bool
     *
     * @throws Exception
     */
    public function save()
    {
        $dependencyInjector = $this->_dependencyInjector;
 
        if (!is_object($dependencyInjector)) {
            throw new Exception(
                "A dependency injector container is required to obtain the services related to the ODM"
            );
        }
 
        $source = $this->getSource();
 
        if (empty($source)) {
            throw new Exception("Method getSource() returns empty string");
        }
 
        $connection = $this->getConnection();
 
        $collection = $connection->selectCollection($source);
 
        $exists = $this->_exists($collection);
 
        if (false === $exists) {
            $this->_operationMade = self::OP_CREATE;
        } else {
            $this->_operationMade = self::OP_UPDATE;
        }
 
        /**
         * The messages added to the validator are reset here
         */
        $this->_errorMessages = [];
 
        $disableEvents = self::$_disableEvents;
 
        /**
         * Execute the preSave hook
         */
        if (false === $this->_preSave($dependencyInjector, $disableEvents, $exists)) {
            return false;
        }
 
        $data = $this->toArray();
 
        /**
         * We always use safe stores to get the success state
         * Save the document
         */
        switch ($this->_operationMade) {
            case self::OP_CREATE:
                $status = $collection->insertOne($data);
                break;
 
            case self::OP_UPDATE:
                unset($data['_id']);
                $status = $collection->updateOne(['_id' => $this->_id], ['$set' => $data]);
                break;
 
            default:
                throw new Exception('Invalid operation requested for ' . __METHOD__);
        }
 
        $success = false;
 
        if ($status->isAcknowledged()) {
            $success = true;
 
            if (false === $exists) {
                $this->_id = $status->getInsertedId();
                $this->_dirtyState = self::DIRTY_STATE_PERSISTENT;
            }
        }
 
        /**
         * Call the postSave hooks
         */
        return $this->_postSave($disableEvents, $success, $exists);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param mixed $id
     *
     * @return array
     */
    public static function findById($id)
    {
        if (!is_object($id)) {
            $classname = get_called_class();
            $collection = new $classname();
 
            /** @var MongoCollection $collection */
            if ($collection->getCollectionManager()->isUsingImplicitObjectIds($collection)) {
                $mongoId = new ObjectID($id);
            } else {
                $mongoId = $id;
            }
        } else {
            $mongoId = $id;
        }
 
        return static::findFirst([["_id" => $mongoId]]);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param  array|null $parameters
     * @return array
     */
    public static function findFirst(array $parameters = null)
    {
        $className = get_called_class();
 
        /** @var MongoCollection $collection */
        $collection = new $className();
 
        $connection = $collection->getConnection();
 
        return static::_getResultset($parameters, $collection, $connection, true);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param array               $params
     * @param CollectionInterface $collection
     * @param \MongoDb            $connection
     * @param bool                $unique
     *
     * @return array
     * @throws Exception
     * @codingStandardsIgnoreStart
     */
    protected static function _getResultset($params, CollectionInterface $collection, $connection, $unique)
    {
        /**
         * @codingStandardsIgnoreEnd
         * Check if "class" clause was defined
         */
        if (isset($params['class'])) {
            $classname = $params['class'];
            $base = new $classname();
 
            if (!$base instanceof CollectionInterface || $base instanceof Document) {
                throw new Exception(
                    sprintf(
                        'Object of class "%s" must be an implementation of %s or an instance of %s',
                        get_class($base),
                        CollectionInterface::class,
                        Document::class
                    )
                );
            }
        } else {
            $base = $collection;
        }
 
        if ($base instanceof PhalconCollection) {
            $base->setDirtyState(PhalconCollection::DIRTY_STATE_PERSISTENT);
        }
 
        $source = $collection->getSource();
 
        if (empty($source)) {
            throw new Exception("Method getSource() returns empty string");
        }
 
        /**
         * @var \Phalcon\Db\Adapter\MongoDB\Collection $mongoCollection
         */
        $mongoCollection = $connection->selectCollection($source);
 
        if (!is_object($mongoCollection)) {
            throw new Exception("Couldn't select mongo collection");
        }
 
        $conditions = [];
 
        if (isset($params[0])||isset($params['conditions'])) {
            $conditions = (isset($params[0]))?$params[0]:$params['conditions'];
        }
 
        /**
         * Convert the string to an array
         */
        if (!is_array($conditions)) {
            throw new Exception("Find parameters must be an array");
        }
 
        $options = [];
 
        /**
         * Check if a "limit" clause was defined
         */
        if (isset($params['limit'])) {
            $limit = $params['limit'];
 
            $options['limit'] = (int)$limit;
 
            if ($unique) {
                $options['limit'] = 1;
            }
        }
 
        /**
         * Check if a "sort" clause was defined
         */
        if (isset($params['sort'])) {
            $sort = $params["sort"];
 
            $options['sort'] = $sort;
        }
 
        /**
         * Check if a "skip" clause was defined
         */
        if (isset($params['skip'])) {
            $skip = $params["skip"];
 
            $options['skip'] = (int)$skip;
        }
 
        if (isset($params['fields']) && is_array($params['fields']) && !empty($params['fields'])) {
            $options['projection'] = [];
 
            foreach ($params['fields'] as $key => $show) {
                $options['projection'][$key] = $show;
            }
        }
 
        /**
         * Perform the find
         */
        $cursor = $mongoCollection->find($conditions, $options);
 
 
        $cursor->setTypeMap(['root' => get_class($base), 'document' => 'array']);
 
        if (true === $unique) {
            /**
             * Looking for only the first result.
             */
            return current($cursor->toArray());
        }
 
        /**
         * Requesting a complete resultset
         */
        $collections = [];
        foreach ($cursor as $document) {
            /**
             * Assign the values to the base object
             */
            $collections[] = $document;
        }
 
        return $collections;
    }
 
    /**
     * {@inheritdoc}
     *
     * <code>
     *    $robot = Robots::findFirst();
     *    $robot->delete();
     *
     *    foreach (Robots::find() as $robot) {
     *        $robot->delete();
     *    }
     * </code>
     */
    public function delete()
    {
        if (!$id = $this->_id) {
            throw new Exception("The document cannot be deleted because it doesn't exist");
        }
 
        $disableEvents = self::$_disableEvents;
 
        if (!$disableEvents) {
            if (false === $this->fireEventCancel("beforeDelete")) {
                return false;
            }
        }
 
        if (true === $this->_skipped) {
            return true;
        }
 
        $connection = $this->getConnection();
 
        $source = $this->getSource();
        if (empty($source)) {
            throw new Exception("Method getSource() returns empty string");
        }
 
        /**
         * Get the Collection
         *
         * @var AdapterCollection $collection
         */
        $collection = $connection->selectCollection($source);
 
        if (is_object($id)) {
            $mongoId = $id;
        } else {
            if ($this->_modelsManager->isUsingImplicitObjectIds($this)) {
                $mongoId = new ObjectID($id);
            } else {
                $mongoId = $id;
            }
        }
 
        $success = false;
 
        /**
         * Remove the instance
         */
        $status = $collection->deleteOne(['_id' => $mongoId], ['w' => true]);
 
        if ($status->isAcknowledged()) {
            $success = true;
 
            $this->fireEvent("afterDelete");
            $this->_dirtyState = self::DIRTY_STATE_DETACHED;
        }
 
        return $success;
    }
 
    /**
     * {@inheritdoc}
     *
     * @param  \MongoCollection $collection
     * @return boolean
     * @codingStandardsIgnoreStart
     */
    protected function _exists($collection)
    {
        // @codingStandardsIgnoreStart
        if (!$id = $this->_id) {
            return false;
        }
 
        if (!$this->_dirtyState) {
            return true;
        }
 
        if (is_object($id)) {
            $mongoId = $id;
        } else {
            /**
             * Check if the model use implicit ids
             */
            if ($this->_modelsManager->isUsingImplicitObjectIds($this)) {
                $mongoId = new ObjectID($id);
            } else {
                $mongoId = $id;
            }
        }
 
        /**
         * Perform the count using the function provided by the driver
         */
        $exists = $collection->count(["_id" => $mongoId]) > 0;
 
        if ($exists) {
            $this->_dirtyState = self::DIRTY_STATE_PERSISTENT;
        } else {
            $this->_dirtyState = self::DIRTY_STATE_TRANSIENT;
        }
 
        return $exists;
    }
 
    /**
     * {@inheritdoc}
     *
     * @param string $eventName
     * @return bool
     */
    public function fireEventCancel($eventName)
    {
        /**
         * Check if there is a method with the same name of the event
         */
        if (method_exists($this, $eventName)) {
            if (false === $this->{$eventName}()) {
                return false;
            }
        }
 
 
        /**
         * Send a notification to the events manager
         */
        if (false === $this->_modelsManager->notifyEvent($eventName, $this)) {
            return false;
        }
 
        return true;
    }
 
    /**
     * {@inheritdoc}
     *
     * @todo
     * @param string $field
     * @param null $conditions
     * @param null $finalize
     *
     * @throws Exception
     */
    public static function summatory($field, $conditions = null, $finalize = null)
    {
        throw new Exception('The summatory() method is not implemented in the new Mvc MongoCollection');
    }
 
    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function create()
    {
        /** @var \Phalcon\Db\Adapter\MongoDB\Collection $collection */
        $collection = $this->prepareCU();
 
        /**
         * Check the dirty state of the current operation to update the current operation
         */
        $this->_operationMade = self::OP_CREATE;
 
        /**
         * The messages added to the validator are reset here
         */
        $this->_errorMessages = [];
 
        /**
         * Execute the preSave hook
         */
        if ($this->_preSave($this->_dependencyInjector, self::$_disableEvents, false) === false) {
            return false;
        }
 
        $data = $this->toArray();
        $success = false;
 
        /**
         * We always use safe stores to get the success state
         * Save the document
         */
        $result = $collection->insert($data, ['writeConcern' => new WriteConcern(1)]);
        if ($result instanceof InsertOneResult && $result->getInsertedId()) {
            $success = true;
            $this->_dirtyState = self::DIRTY_STATE_PERSISTENT;
            $this->_id = $result->getInsertedId();
        }
 
        /**
         * Call the postSave hooks
         */
        return $this->_postSave(self::$_disableEvents, $success, false);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param array $data
     */
    public function bsonUnserialize(array $data)
    {
        $this->setDI(Di::getDefault());
        $this->_modelsManager = Di::getDefault()->getShared('collectionManager');
 
        foreach ($data as $key => $val) {
            $this->{$key} = $val;
        }
 
        if (method_exists($this, "afterFetch")) {
            $this->afterFetch();
        }
    }
}
#2Phalcon\Mvc\MongoCollection::_getResultset(Array([0] => Array([ip] => 34.204.11.236)), Object(Coam\App\Collections\DiSecurityCollection), Object(Phalcon\Db\Adapter\MongoDB\Database), true)
/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Mvc/MongoCollection.php (192)
<?php
 
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2016 Phalcon Team (https://www.phalconphp.com)      |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file LICENSE.txt.                             |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to license@phalconphp.com so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: Ben Casey <bcasey@tigerstrikemedia.com>                       |
  +------------------------------------------------------------------------+
*/
 
namespace Phalcon\Mvc;
 
use Phalcon\Di;
use MongoDB\BSON\ObjectID;
use MongoDB\Driver\WriteConcern;
use MongoDB\BSON\Unserializable;
use Phalcon\Mvc\Collection\Document;
use Phalcon\Mvc\Collection\Exception;
use Phalcon\Mvc\Collection\ManagerInterface;
use Phalcon\Db\Adapter\MongoDB\InsertOneResult;
use Phalcon\Mvc\Collection as PhalconCollection;
use Phalcon\Db\Adapter\MongoDB\Collection as AdapterCollection;
 
/**
 * Class MongoCollection
 *
 * @property ManagerInterface _modelsManager
 * @package Phalcon\Mvc
 */
abstract class MongoCollection extends PhalconCollection implements Unserializable
{
    // @codingStandardsIgnoreStart
    static protected $_disableEvents;
    // @codingStandardsIgnoreEnd
 
    /**
     * {@inheritdoc}
     *
     * @param mixed $id
     */
    public function setId($id)
    {
        if (is_object($id)) {
            $this->_id = $id;
            return;
        }
 
        if ($this->_modelsManager->isUsingImplicitObjectIds($this)) {
            $this->_id = new ObjectID($id);
            return;
        }
 
        $this->_id = $id;
    }
 
    /**
     * {@inheritdoc}
     *
     * @return bool
     *
     * @throws Exception
     */
    public function save()
    {
        $dependencyInjector = $this->_dependencyInjector;
 
        if (!is_object($dependencyInjector)) {
            throw new Exception(
                "A dependency injector container is required to obtain the services related to the ODM"
            );
        }
 
        $source = $this->getSource();
 
        if (empty($source)) {
            throw new Exception("Method getSource() returns empty string");
        }
 
        $connection = $this->getConnection();
 
        $collection = $connection->selectCollection($source);
 
        $exists = $this->_exists($collection);
 
        if (false === $exists) {
            $this->_operationMade = self::OP_CREATE;
        } else {
            $this->_operationMade = self::OP_UPDATE;
        }
 
        /**
         * The messages added to the validator are reset here
         */
        $this->_errorMessages = [];
 
        $disableEvents = self::$_disableEvents;
 
        /**
         * Execute the preSave hook
         */
        if (false === $this->_preSave($dependencyInjector, $disableEvents, $exists)) {
            return false;
        }
 
        $data = $this->toArray();
 
        /**
         * We always use safe stores to get the success state
         * Save the document
         */
        switch ($this->_operationMade) {
            case self::OP_CREATE:
                $status = $collection->insertOne($data);
                break;
 
            case self::OP_UPDATE:
                unset($data['_id']);
                $status = $collection->updateOne(['_id' => $this->_id], ['$set' => $data]);
                break;
 
            default:
                throw new Exception('Invalid operation requested for ' . __METHOD__);
        }
 
        $success = false;
 
        if ($status->isAcknowledged()) {
            $success = true;
 
            if (false === $exists) {
                $this->_id = $status->getInsertedId();
                $this->_dirtyState = self::DIRTY_STATE_PERSISTENT;
            }
        }
 
        /**
         * Call the postSave hooks
         */
        return $this->_postSave($disableEvents, $success, $exists);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param mixed $id
     *
     * @return array
     */
    public static function findById($id)
    {
        if (!is_object($id)) {
            $classname = get_called_class();
            $collection = new $classname();
 
            /** @var MongoCollection $collection */
            if ($collection->getCollectionManager()->isUsingImplicitObjectIds($collection)) {
                $mongoId = new ObjectID($id);
            } else {
                $mongoId = $id;
            }
        } else {
            $mongoId = $id;
        }
 
        return static::findFirst([["_id" => $mongoId]]);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param  array|null $parameters
     * @return array
     */
    public static function findFirst(array $parameters = null)
    {
        $className = get_called_class();
 
        /** @var MongoCollection $collection */
        $collection = new $className();
 
        $connection = $collection->getConnection();
 
        return static::_getResultset($parameters, $collection, $connection, true);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param array               $params
     * @param CollectionInterface $collection
     * @param \MongoDb            $connection
     * @param bool                $unique
     *
     * @return array
     * @throws Exception
     * @codingStandardsIgnoreStart
     */
    protected static function _getResultset($params, CollectionInterface $collection, $connection, $unique)
    {
        /**
         * @codingStandardsIgnoreEnd
         * Check if "class" clause was defined
         */
        if (isset($params['class'])) {
            $classname = $params['class'];
            $base = new $classname();
 
            if (!$base instanceof CollectionInterface || $base instanceof Document) {
                throw new Exception(
                    sprintf(
                        'Object of class "%s" must be an implementation of %s or an instance of %s',
                        get_class($base),
                        CollectionInterface::class,
                        Document::class
                    )
                );
            }
        } else {
            $base = $collection;
        }
 
        if ($base instanceof PhalconCollection) {
            $base->setDirtyState(PhalconCollection::DIRTY_STATE_PERSISTENT);
        }
 
        $source = $collection->getSource();
 
        if (empty($source)) {
            throw new Exception("Method getSource() returns empty string");
        }
 
        /**
         * @var \Phalcon\Db\Adapter\MongoDB\Collection $mongoCollection
         */
        $mongoCollection = $connection->selectCollection($source);
 
        if (!is_object($mongoCollection)) {
            throw new Exception("Couldn't select mongo collection");
        }
 
        $conditions = [];
 
        if (isset($params[0])||isset($params['conditions'])) {
            $conditions = (isset($params[0]))?$params[0]:$params['conditions'];
        }
 
        /**
         * Convert the string to an array
         */
        if (!is_array($conditions)) {
            throw new Exception("Find parameters must be an array");
        }
 
        $options = [];
 
        /**
         * Check if a "limit" clause was defined
         */
        if (isset($params['limit'])) {
            $limit = $params['limit'];
 
            $options['limit'] = (int)$limit;
 
            if ($unique) {
                $options['limit'] = 1;
            }
        }
 
        /**
         * Check if a "sort" clause was defined
         */
        if (isset($params['sort'])) {
            $sort = $params["sort"];
 
            $options['sort'] = $sort;
        }
 
        /**
         * Check if a "skip" clause was defined
         */
        if (isset($params['skip'])) {
            $skip = $params["skip"];
 
            $options['skip'] = (int)$skip;
        }
 
        if (isset($params['fields']) && is_array($params['fields']) && !empty($params['fields'])) {
            $options['projection'] = [];
 
            foreach ($params['fields'] as $key => $show) {
                $options['projection'][$key] = $show;
            }
        }
 
        /**
         * Perform the find
         */
        $cursor = $mongoCollection->find($conditions, $options);
 
 
        $cursor->setTypeMap(['root' => get_class($base), 'document' => 'array']);
 
        if (true === $unique) {
            /**
             * Looking for only the first result.
             */
            return current($cursor->toArray());
        }
 
        /**
         * Requesting a complete resultset
         */
        $collections = [];
        foreach ($cursor as $document) {
            /**
             * Assign the values to the base object
             */
            $collections[] = $document;
        }
 
        return $collections;
    }
 
    /**
     * {@inheritdoc}
     *
     * <code>
     *    $robot = Robots::findFirst();
     *    $robot->delete();
     *
     *    foreach (Robots::find() as $robot) {
     *        $robot->delete();
     *    }
     * </code>
     */
    public function delete()
    {
        if (!$id = $this->_id) {
            throw new Exception("The document cannot be deleted because it doesn't exist");
        }
 
        $disableEvents = self::$_disableEvents;
 
        if (!$disableEvents) {
            if (false === $this->fireEventCancel("beforeDelete")) {
                return false;
            }
        }
 
        if (true === $this->_skipped) {
            return true;
        }
 
        $connection = $this->getConnection();
 
        $source = $this->getSource();
        if (empty($source)) {
            throw new Exception("Method getSource() returns empty string");
        }
 
        /**
         * Get the Collection
         *
         * @var AdapterCollection $collection
         */
        $collection = $connection->selectCollection($source);
 
        if (is_object($id)) {
            $mongoId = $id;
        } else {
            if ($this->_modelsManager->isUsingImplicitObjectIds($this)) {
                $mongoId = new ObjectID($id);
            } else {
                $mongoId = $id;
            }
        }
 
        $success = false;
 
        /**
         * Remove the instance
         */
        $status = $collection->deleteOne(['_id' => $mongoId], ['w' => true]);
 
        if ($status->isAcknowledged()) {
            $success = true;
 
            $this->fireEvent("afterDelete");
            $this->_dirtyState = self::DIRTY_STATE_DETACHED;
        }
 
        return $success;
    }
 
    /**
     * {@inheritdoc}
     *
     * @param  \MongoCollection $collection
     * @return boolean
     * @codingStandardsIgnoreStart
     */
    protected function _exists($collection)
    {
        // @codingStandardsIgnoreStart
        if (!$id = $this->_id) {
            return false;
        }
 
        if (!$this->_dirtyState) {
            return true;
        }
 
        if (is_object($id)) {
            $mongoId = $id;
        } else {
            /**
             * Check if the model use implicit ids
             */
            if ($this->_modelsManager->isUsingImplicitObjectIds($this)) {
                $mongoId = new ObjectID($id);
            } else {
                $mongoId = $id;
            }
        }
 
        /**
         * Perform the count using the function provided by the driver
         */
        $exists = $collection->count(["_id" => $mongoId]) > 0;
 
        if ($exists) {
            $this->_dirtyState = self::DIRTY_STATE_PERSISTENT;
        } else {
            $this->_dirtyState = self::DIRTY_STATE_TRANSIENT;
        }
 
        return $exists;
    }
 
    /**
     * {@inheritdoc}
     *
     * @param string $eventName
     * @return bool
     */
    public function fireEventCancel($eventName)
    {
        /**
         * Check if there is a method with the same name of the event
         */
        if (method_exists($this, $eventName)) {
            if (false === $this->{$eventName}()) {
                return false;
            }
        }
 
 
        /**
         * Send a notification to the events manager
         */
        if (false === $this->_modelsManager->notifyEvent($eventName, $this)) {
            return false;
        }
 
        return true;
    }
 
    /**
     * {@inheritdoc}
     *
     * @todo
     * @param string $field
     * @param null $conditions
     * @param null $finalize
     *
     * @throws Exception
     */
    public static function summatory($field, $conditions = null, $finalize = null)
    {
        throw new Exception('The summatory() method is not implemented in the new Mvc MongoCollection');
    }
 
    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function create()
    {
        /** @var \Phalcon\Db\Adapter\MongoDB\Collection $collection */
        $collection = $this->prepareCU();
 
        /**
         * Check the dirty state of the current operation to update the current operation
         */
        $this->_operationMade = self::OP_CREATE;
 
        /**
         * The messages added to the validator are reset here
         */
        $this->_errorMessages = [];
 
        /**
         * Execute the preSave hook
         */
        if ($this->_preSave($this->_dependencyInjector, self::$_disableEvents, false) === false) {
            return false;
        }
 
        $data = $this->toArray();
        $success = false;
 
        /**
         * We always use safe stores to get the success state
         * Save the document
         */
        $result = $collection->insert($data, ['writeConcern' => new WriteConcern(1)]);
        if ($result instanceof InsertOneResult && $result->getInsertedId()) {
            $success = true;
            $this->_dirtyState = self::DIRTY_STATE_PERSISTENT;
            $this->_id = $result->getInsertedId();
        }
 
        /**
         * Call the postSave hooks
         */
        return $this->_postSave(self::$_disableEvents, $success, false);
    }
 
    /**
     * {@inheritdoc}
     *
     * @param array $data
     */
    public function bsonUnserialize(array $data)
    {
        $this->setDI(Di::getDefault());
        $this->_modelsManager = Di::getDefault()->getShared('collectionManager');
 
        foreach ($data as $key => $val) {
            $this->{$key} = $val;
        }
 
        if (method_exists($this, "afterFetch")) {
            $this->afterFetch();
        }
    }
}
#3Phalcon\Mvc\MongoCollection::findFirst(Array([0] => Array([ip] => 34.204.11.236)))
/data/home/yzhang/WebCoam/Web/Applications/Library/DiSecurityControl.php (31)
<?php
namespace Coam\App\Library;
 
use Coam;
use Coam\App\Collections;
use Coam\App\Library;
use Coam\App\Models;
use Coam\App\Library\Zz_Api;
use \Phalcon\Mvc\User\Plugin;
use Coam\App\Collections\DiSecurityCollection;
 
//use \Phalcon\Mvc\User\Component;
class DiSecurityControl extends Plugin
{
    private $disc;// InterfaceSecurityControl
    private $diMcsList;
 
    public function __construct()
    {
        $ip = $this->request->getClientAddress();
        // 获取 disc 对象...
        $this->loadIscCollection($ip);
        $this->diMcsList = $this->disc->diMcsList;
    }
 
    // 加载 disc 数据...
    private function loadIscCollection($ip = "0.0.0.0")
    {
        // ip 访问控制...
        $this->disc = DiSecurityCollection::findFirst(array(
            array("ip" => $ip)
        ));
        if (!$this->disc) {
            $this->disc = new DiSecurityCollection();
            $this->disc->ip = $ip;
            //初始化访问数据
            //$this->disc->initializeData();
            $this->disc->diMcsList = [];
            //$this->disc->save();
        }
    }
 
    // 校验并添加用户访问控制请求
    public function iMcaSecurityControl($mca)
    {
        lg_debug("(new DiSecurityControl())->iMcaSecurityControl({$mca})....");
        list($module, $controller, $action) = explode("/", $mca);
 
        // 接口限速列表...
        $scInterfaceList = DiSecurityCollection::$scInterfaceList;
        $scInterfaceKeys = array_keys($scInterfaceList);
        if (!in_array($mca, $scInterfaceKeys)) return true;
        $scInterfaceInfo = $scInterfaceList[$mca];
 
        // 限速配置...
        $sc_code = $scInterfaceInfo["sc_code"];
        $sc_way = $scInterfaceInfo["sc_way"];
        $sc_rate = $scInterfaceInfo["sc_rate"];
        $sc_it = $scInterfaceInfo["sc_it"];
        $sc_ot = $scInterfaceInfo["sc_ot"];
 
        // 获取接口访问权限...
        $diMcsInfo = null;
        if (!isset($this->diMcsList[$mca])) {
            $diMcsInfo = $this->disc->initDiMcsInfo($mca);
        } else {
            $diMcsInfo = $this->diMcsList[$mca];
        }
 
        // 限速设置...
        $asc_code = $diMcsInfo["asc_code"];
        $asc_way = $diMcsInfo["asc_way"];
        $asc_rate = $diMcsInfo["asc_rate"];
 
        // 更新请求访问数据量
        $api_ti_n = intval(time() / $sc_it);
        $api_to_n = intval(time() / $sc_ot);
        $api_ti = $diMcsInfo["api_ti"];
        $api_to = $diMcsInfo["api_to"];
 
        // 接口限速类型...
        switch ($asc_way) {
            case "InterfaceRateLimit":
                // TODO...
                break;
            case "InterfaceRateLock":
                // TODO...
                break;
            default:
                // TODO...
                Zz_Api::io(40000, "unknown [$ asc_way: $asc_way] error");
                break;
        }
 
        // 如果未到达下一统计周期,则直接返回失败...
        if (($asc_code !== 200) && ($api_to_n === $api_to)) return $asc_code;
 
        // 如果到达下一统计周期,则清零统计计数...
        if ($api_ti_n !== $api_ti) {
            $diMcsInfo["asc_code"] = 200;
            $diMcsInfo["aiTimes"] = 0;
        }
 
        // 如果是有效的请求,则更新统计计数...
        $diMcsInfo["api_ti"] = $api_ti_n;
        $diMcsInfo["api_to"] = $api_to_n;
        $diMcsInfo["aiTimes"] += 1;
        $diMcsInfo["atTimes"] += 1;
        $diMcsInfo["accessTime"] = date("Y-m-d H:i:s");
 
        // 如果错误量大于标定的值,则关闭访问权限 10 分钟超过3次
        if ($diMcsInfo["aiTimes"] > $asc_rate) {
            // 设限-直到下一循环周期
            $diMcsInfo["asc_code"] = $sc_code;
            $diMcsInfo["aeTimes"] += 1; // 增加请求限制总次数
        }
 
        // 更新访问控制数据...
        $this->diMcsList[$mca] = $diMcsInfo;
        $this->disc->diMcsList = $this->diMcsList;
        //$this->disc->save();
        if ($this->disc->save() === false) {
            lg_info("##[CASC]@@||....");
            foreach ($this->disc->getMessages() as $m) lg_info($m);
        }
 
        // 设定 HTTP 返回限定状态码...
        return $asc_code;
    }
 
    // 清除用户访问控制请求
    public function cMcaSecurityControl($mca = "*")
    {
        lg_debug("(new DiSecurityControl())->cMcaSecurityControl({$mca})....");
        list($module, $controller, $action) = explode("/", $mca);
 
        // 接口限速列表...
        $scInterfaceList = DiSecurityCollection::$scInterfaceList;
        $scInterfaceKeys = array_keys($scInterfaceList);
        if (!in_array($mca, $scInterfaceKeys)) Zz_Api::io(40000, "ScInterfaceKeys [mca: {$mca}] not found error...", ["scInterfaceKeys" => $scInterfaceKeys]);
        //$scInterfaceInfo = $scInterfaceList[$mca];
 
        // 更新 diMcsList 列表...
        if ($mca == "*") {
            $this->diMcsList = [];
        } else {
            unset($this->diMcsList[$mca]);
        }
 
        $this->disc->diMcsList = $this->diMcsList;
 
        //更新数据
        //$this->disc->save();
        if ($this->disc->save() === false) {
            lg_info("##[CASC]@@||....");
            foreach ($this->disc->getMessages() as $m) lg_info($m);
        }
    }
}
#4Coam\App\Library\DiSecurityControl->loadIscCollection(34.204.11.236)
/data/home/yzhang/WebCoam/Web/Applications/Library/DiSecurityControl.php (22)
<?php
namespace Coam\App\Library;
 
use Coam;
use Coam\App\Collections;
use Coam\App\Library;
use Coam\App\Models;
use Coam\App\Library\Zz_Api;
use \Phalcon\Mvc\User\Plugin;
use Coam\App\Collections\DiSecurityCollection;
 
//use \Phalcon\Mvc\User\Component;
class DiSecurityControl extends Plugin
{
    private $disc;// InterfaceSecurityControl
    private $diMcsList;
 
    public function __construct()
    {
        $ip = $this->request->getClientAddress();
        // 获取 disc 对象...
        $this->loadIscCollection($ip);
        $this->diMcsList = $this->disc->diMcsList;
    }
 
    // 加载 disc 数据...
    private function loadIscCollection($ip = "0.0.0.0")
    {
        // ip 访问控制...
        $this->disc = DiSecurityCollection::findFirst(array(
            array("ip" => $ip)
        ));
        if (!$this->disc) {
            $this->disc = new DiSecurityCollection();
            $this->disc->ip = $ip;
            //初始化访问数据
            //$this->disc->initializeData();
            $this->disc->diMcsList = [];
            //$this->disc->save();
        }
    }
 
    // 校验并添加用户访问控制请求
    public function iMcaSecurityControl($mca)
    {
        lg_debug("(new DiSecurityControl())->iMcaSecurityControl({$mca})....");
        list($module, $controller, $action) = explode("/", $mca);
 
        // 接口限速列表...
        $scInterfaceList = DiSecurityCollection::$scInterfaceList;
        $scInterfaceKeys = array_keys($scInterfaceList);
        if (!in_array($mca, $scInterfaceKeys)) return true;
        $scInterfaceInfo = $scInterfaceList[$mca];
 
        // 限速配置...
        $sc_code = $scInterfaceInfo["sc_code"];
        $sc_way = $scInterfaceInfo["sc_way"];
        $sc_rate = $scInterfaceInfo["sc_rate"];
        $sc_it = $scInterfaceInfo["sc_it"];
        $sc_ot = $scInterfaceInfo["sc_ot"];
 
        // 获取接口访问权限...
        $diMcsInfo = null;
        if (!isset($this->diMcsList[$mca])) {
            $diMcsInfo = $this->disc->initDiMcsInfo($mca);
        } else {
            $diMcsInfo = $this->diMcsList[$mca];
        }
 
        // 限速设置...
        $asc_code = $diMcsInfo["asc_code"];
        $asc_way = $diMcsInfo["asc_way"];
        $asc_rate = $diMcsInfo["asc_rate"];
 
        // 更新请求访问数据量
        $api_ti_n = intval(time() / $sc_it);
        $api_to_n = intval(time() / $sc_ot);
        $api_ti = $diMcsInfo["api_ti"];
        $api_to = $diMcsInfo["api_to"];
 
        // 接口限速类型...
        switch ($asc_way) {
            case "InterfaceRateLimit":
                // TODO...
                break;
            case "InterfaceRateLock":
                // TODO...
                break;
            default:
                // TODO...
                Zz_Api::io(40000, "unknown [$ asc_way: $asc_way] error");
                break;
        }
 
        // 如果未到达下一统计周期,则直接返回失败...
        if (($asc_code !== 200) && ($api_to_n === $api_to)) return $asc_code;
 
        // 如果到达下一统计周期,则清零统计计数...
        if ($api_ti_n !== $api_ti) {
            $diMcsInfo["asc_code"] = 200;
            $diMcsInfo["aiTimes"] = 0;
        }
 
        // 如果是有效的请求,则更新统计计数...
        $diMcsInfo["api_ti"] = $api_ti_n;
        $diMcsInfo["api_to"] = $api_to_n;
        $diMcsInfo["aiTimes"] += 1;
        $diMcsInfo["atTimes"] += 1;
        $diMcsInfo["accessTime"] = date("Y-m-d H:i:s");
 
        // 如果错误量大于标定的值,则关闭访问权限 10 分钟超过3次
        if ($diMcsInfo["aiTimes"] > $asc_rate) {
            // 设限-直到下一循环周期
            $diMcsInfo["asc_code"] = $sc_code;
            $diMcsInfo["aeTimes"] += 1; // 增加请求限制总次数
        }
 
        // 更新访问控制数据...
        $this->diMcsList[$mca] = $diMcsInfo;
        $this->disc->diMcsList = $this->diMcsList;
        //$this->disc->save();
        if ($this->disc->save() === false) {
            lg_info("##[CASC]@@||....");
            foreach ($this->disc->getMessages() as $m) lg_info($m);
        }
 
        // 设定 HTTP 返回限定状态码...
        return $asc_code;
    }
 
    // 清除用户访问控制请求
    public function cMcaSecurityControl($mca = "*")
    {
        lg_debug("(new DiSecurityControl())->cMcaSecurityControl({$mca})....");
        list($module, $controller, $action) = explode("/", $mca);
 
        // 接口限速列表...
        $scInterfaceList = DiSecurityCollection::$scInterfaceList;
        $scInterfaceKeys = array_keys($scInterfaceList);
        if (!in_array($mca, $scInterfaceKeys)) Zz_Api::io(40000, "ScInterfaceKeys [mca: {$mca}] not found error...", ["scInterfaceKeys" => $scInterfaceKeys]);
        //$scInterfaceInfo = $scInterfaceList[$mca];
 
        // 更新 diMcsList 列表...
        if ($mca == "*") {
            $this->diMcsList = [];
        } else {
            unset($this->diMcsList[$mca]);
        }
 
        $this->disc->diMcsList = $this->diMcsList;
 
        //更新数据
        //$this->disc->save();
        if ($this->disc->save() === false) {
            lg_info("##[CASC]@@||....");
            foreach ($this->disc->getMessages() as $m) lg_info($m);
        }
    }
}
#5Coam\App\Library\DiSecurityControl->__construct()
/data/home/yzhang/WebCoam/Web/Applications/Library/DiSecurityBase.php (221)
<?php
 
namespace Coam\App\Library;
 
use Coam;
use Coam\App\Collections;
use Coam\App\Library;
use Coam\App\Models;
use Coam\App\Library\Zz_Api;
use \Phalcon\Events\Event,
    \Phalcon\Mvc\User\Plugin,
    \Phalcon\Mvc\Dispatcher,
    \Phalcon\Acl;
 
/**
 * Security
 * This is the security plugin which controls that users only have access to the modules they're assigned to
 */
class DiSecurityBase extends Plugin
{
    // 请求的接口
    public $requestPathInterface;
    public $module;
    public $controller;
    public $action;
 
    // 角色列表 - 当前登录用户账户角色
    public $role_tag_list;
    public $roles;
    public $role;
 
    // 账户等级列表 - 当前登录用户账户等级
    public $level_tag_list;
    public $levels;
    public $level;
 
    // 通用资源权限配置 ...
    protected $cMcaRoleResources;
    protected $cMcaLevelResources;
    protected $aclAllowed;
    protected $roleAcl;
    protected $roleAclAllowed;
    protected $levelAcl;
    protected $levelAclAllowed;
 
    // token 验证相关...
    public $requestMethod = null;
    public $requestToken = null;
 
    // 其它配置变量
    protected $cross_dos = []; // 配置访问可跨的根域 ...
 
    public function __construct($dependencyInjector)
    {
        $this->_dependencyInjector = $dependencyInjector;
 
        // 设定角色列表 ["*" =>AEFMHOTICG]
        //$this->role_tag_list = ["Administrator" => "A", "Executive" => "E", "Financial" => "F", "Market" => "M", "HumanResource" => "H", "Operation" => "O", "Technical" => "T", "Information" => "I", "Supplier" => "S", "Manager" => "M", "Customer" => "C", "Guests" => "G"];
        $this->role_tag_list = ["Administrator" => "A", "Customer" => "C", "Driver" => "D", "Logistics" => "L", "Park" => "P", "Enterprise" => "E", "Supplier" => "S", "Guests" => "G"];
        $this->roles = array(
            // 超级管理员-[A] (Administrator)
            'administrator' => new \Phalcon\Acl\Role('Administrator'),
            // 其它一般权限-[C]
            'customer' => new \Phalcon\Acl\Role('Customer'),
            // 供应商权限-[L]
            'driver' => new \Phalcon\Acl\Role('Driver'),
            // 供应商权限-[L]
            'logistics' => new \Phalcon\Acl\Role('Logistics'),
            // 供应商权限-[L]
            'park' => new \Phalcon\Acl\Role('Park'),
            // 企业权限-[E]
            'enterprise' => new \Phalcon\Acl\Role('Enterprise'),
            // 供应商权限-[S]
            'supplier' => new \Phalcon\Acl\Role('Supplier'),
            // 访客-[G]
            'guests' => new \Phalcon\Acl\Role('Guests')
        );
 
        // 设定角色列表 ["*" =>AEFMHOTIX]
        $this->level_tag_list = ["Administrator" => "A", "Executive" => "E", "Financial" => "F", "Market" => "M", "Hon" => "H", "Operation" => "O", "Technical" => "T", "Information" => "I", "Supplier" => "S", "Xal" => "X"];
        $this->levels = array(
            // 超级管理员-[A] (Administrator)
            'administrator' => new \Phalcon\Acl\Role('Administrator'),
            // 总经办-[E] CEO(Chief Executive Officer)
            #'executive' => new \Phalcon\Acl\Role('Executive'),
            // 财务部-[F] CFO(Chief Financial Officer)
            'financial' => new \Phalcon\Acl\Role('Financial'),
            // 市场部-[M] CMO (Chief Marketing Officer)
            'market' => new \Phalcon\Acl\Role('Market'),
            // 首席人事官-[H] (Chief Hong Officer)
            'hon' => new \Phalcon\Acl\Role('Hon'),
            // 首席人事官-[H] (Chief HumanResource Officer)
            #'humanResource' => new \Phalcon\Acl\Role('HumanResource'),
            // 运营部-[O] COO(Chief Operation Officer)
            #'operation' => new \Phalcon\Acl\Role('Operation'),
            // 技术部-[T] CTO(Chief Technology Officer)
            #'technical' => new \Phalcon\Acl\Role('Technical'),
            // 首席信息官-[I] CIO(Chief Information Officer)
            #'information' => new \Phalcon\Acl\Role('Information'),
            // 客户微店账户-[S]
            'supplier' => new \Phalcon\Acl\Role('Supplier'),
            // 空账户-[X]
            'xal' => new \Phalcon\Acl\Role('Xal')
        );
    }
 
    public function loadRoleAcl()
    {
        //if (!isset($this->persistent->roleAcl)) {
        $roleAcl = new \Phalcon\Acl\Adapter\Memory();
        $roleAcl->setDefaultAction(\Phalcon\Acl::DENY);
 
        //Register roles
        foreach ($this->roles as $role) {
            $roleAcl->addRole($role);
        }
 
        // Grant acess to private area to role Users
        foreach ($this->cMcaRoleResources as $controller => $actions) {
 
            // 批量加入 actions,包括 action 通配符 *
            $roleAcl->addResource(new \Phalcon\Acl\Resource($controller), array_keys($actions));
 
            foreach ($actions as $action => $actionALC) {
 
                //Grant access to public areas to both users and guests
                foreach ($this->roles as $role) {
 
                    $role_name = $role->getName();
                    # $role_tag = substr( $role_name, 0, 1 ); // 获取 角色 首字符 tag
                    $role_tag = $this->role_tag_list[$role_name]; // 获取 角色 首字符 tag
                    if ($actionALC === "*" || strpos($actionALC, $role_tag) !== false) {
                        // action 包括通配符 *
                        $roleAcl->allow($role_name, $controller, $action);
 
                        #lg_debug("|DiSecurityBase|getRoleAcl|#[$ role: $role_name][$ controller: $controller][$ action: $action]");
                    }
                }
 
            }
        }
 
        //The acl is stored in session, APC would be useful here too
        $this->persistent->roleAcl = $roleAcl;
        //}
 
        //return $this->persistent->roleAcl;
    }
 
    public function loadLevelAcl()
    {
        //if (!isset($this->persistent->levelAcl)) {
        $levelAcl = new \Phalcon\Acl\Adapter\Memory();
        $levelAcl->setDefaultAction(\Phalcon\Acl::DENY);
 
        //Register roles
        foreach ($this->levels as $level) {
            $levelAcl->addRole($level);
        }
 
        // Grant acess to private area to role Users
        foreach ($this->cMcaLevelResources as $controller => $actions) {
 
            // 批量加入 actions,包括 action 通配符 *
            $levelAcl->addResource(new \Phalcon\Acl\Resource($controller), array_keys($actions));
 
            foreach ($actions as $action => $actionALC) {
 
                //Grant access to public areas to both users and guests
                foreach ($this->levels as $level) {
 
                    $level_name = $level->getName();
                    # $level_tag = substr( $level_name, 0, 1 ); // 获取 等级 首字符 tag
                    $level_tag = $this->level_tag_list[$level_name]; // 获取 等级 首字符 tag
                    if ($actionALC === "*" || strpos($actionALC, $level_tag) !== false) {
                        // action 包括通配符 *
                        $levelAcl->allow($level_name, $controller, $action);
 
                        #lg_debug("|DiSecurityBase|getLevelAcl|#[$ level: $level_name][$ controller: $controller][$ action: $action]");
                    }
                }
 
            }
        }
 
        //The acl is stored in session, APC would be useful here too
        $this->persistent->levelAcl = $levelAcl;
        //}
 
        //return $this->persistent->levelAcl;
    }
 
    // 在[跨域/不跨域]请求时,Nginx不自动返回非 200 错误跨域响应头,在此手动返回跨域响应头...
    public function responseStatusCorsHeader($status_code, $status_tag, $status_steps = "_")
    {
        if (!in_array($status_code, [401, 423, 429, 444])) Zz_Api::io(40005, "Sorry, unsupported response cors error [$ status_tag: $status_tag]....");
        if (!in_array($status_tag, ["Unauthorized", "Locked", "TooManyRequests", "UnverifiedError"])) Zz_Api::io(40005, "Sorry, unsupported response cors error [$ status_tag: $status_tag]...");
 
        // 跨域需要手动发送 跨域请求头,否则会清除 Nginx 设定的 跨域请求头导致 ajax 获取不到
        if (isset($_SERVER['HTTP_ORIGIN']) && in_array(RootServer, $this->cross_dos)) {
            $http_origin = $_SERVER['HTTP_ORIGIN'];
            header("Access-Control-Allow-Origin: $http_origin");
            header('Access-Control-Allow-Credentials:true');
            header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
            header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept');
        }
 
        $this->response->setStatusCode($status_code, $status_tag);
        $this->response->send();
 
        // 记录授权错误日志 ...
        #lg_debug("|#|responseStatusCorsHeader()|[$ status_code: $status_code][$ status_tag: $status_tag][$ status_steps: $status_steps]");
 
        return true;
    }
 
    // 接口访问频率限制...
    public function accessRequestInterface()
    {
        //第一层,访问IP次数限制
        $diSecurityControl = new DiSecurityControl();
        $mca = $this->requestPathInterface;
        $sc_code = $diSecurityControl->iMcaSecurityControl($mca);
        if ($sc_code != 200) return Zz_Api::fo((40000 + $sc_code), "-", ["sc" => $sc_code, "st" => "Locked", "ss" => "_"]);
 
        return Zz_Api::fo(20000, "");
    }
 
    public function authRequestInterface()
    {
        // load and start session
        $this->_dependencyInjector->get("session");
 
        // Post接口[Token]授权验证 ...
        if ($this->request->isPost()) {
 
            //对所有 Post 开启校验模式
            if (in_array($this->module, $this->atModuleList) && !in_array($this->requestPathInterface, $this->unTokenRequestPathList)) {
                lg_debug("Token SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSStarter...");
//                Zz_Api::io(44333, "|#@ acInfo:[acChannel: {$this->acChannel}][acType: {$this->acType}][acWay: {$this->acWay}][acAs: {$this->acAs}][acAsId: {$this->acAsId}][acAsLevel: {$this->acAsLevel}]", $this->disAccountInfo);
 
//                lg_debug("|atModuleList:");
//                lg_debug($this->atModuleList);
//
//                lg_debug("|requestPathInterface:");
//                lg_debug($this->requestPathInterface);
//
//                lg_debug("|unTokenRequestPathList:");
//                lg_debug($this->unTokenRequestPathList);
 
                // 依次取 Token [Header->Post->Get] 并检查 token 是否有效
                //$requestTokenHeader = $this->request->getHeader("HTTP_REQUEST_ACCESS_TOKEN");
                $this->requestMethod = "None";// 初始化
                if (!empty($_GET["token"])) $this->requestToken = $_GET["token"];
                if (!empty($_POST["token"])) $this->requestToken = $_POST["token"];
                $requestHeaderToken = $this->request->getHeader("HTTP_AUTHORIZATION");
                if (!empty($requestHeaderToken)) {
                    $requestTokenInfo = explode(" ", $requestHeaderToken);
                    $this->requestMethod = $requestTokenInfo[0];
                    if (!empty($requestTokenInfo[1])) $this->requestToken = $requestTokenInfo[1];
 
                    lg_debug("Header Token Info:...");
                    lg_debug($requestHeaderToken);
                }
 
                // 必要条件[requestToken]
                if (empty($this->requestToken)) return Zz_Api::fo(40401, "-", ["sc" => 401, "st" => "Unauthorized", "ss" => "_"]);
 
                lg_debug("Request Method Token Info:...");
                lg_debug($this->requestMethod);
                lg_debug($this->requestToken);
 
                // TOKEN Redis Cache...
                $ari_data = null;
                $c_token_rl_tag = "TOKEN:{$this->requestMethod}:{$this->requestToken}";
                //$this->redisDB->delete($c_token_rl_tag);
                if (!$this->redisDB->exists($c_token_rl_tag)) {
 
                    // 如果没有缓存配置,则创建判断权限,检索缓存...
                    $ariInfo = $this->authRequestInterfaceToken();
 
//                    // 强制返回 401 测试...
//                    $this->response->setStatusCode(401, "UnAuthorization");
//                    //Send response to the client
//                    $this->response->send();
//                    return Zz_Api::fo(40401, "-", ["sc" => 401, "st" => "Unauthorized", "ss" => "_"]);
 
                    //lg_debug("ariInfo:");
                    //lg_debug($ariInfo);
 
                    $fo_info = $ariInfo->fo_info;
                    $ari_data = $ariInfo->fo_data;
                    if (!$fo_info->result) return Zz_Api::fo(40401, "-", ["sc" => $ari_data->sc, "st" => $ari_data->st, "ss" => $ari_data->ss]);
 
                    // 设定缓存失效时间...
                    $exp = $ari_data->exp;
                    $_exp = $exp - time();
                    if ($_exp > 10) { // 仅缓存大于 10s 的有效token,排除掉 tmp token
                        $this->redisDB->set($c_token_rl_tag, json_encode($ari_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
                        $this->redisDB->setTimeout($c_token_rl_tag, $_exp);
                    }
                } else {
                    // token 缓存未失效...
                    $ari_data = $this->redisDB->get($c_token_rl_tag);
                    $ari_data = json_decode($ari_data);
                }
 
                // 获取并设置[Token]认证结果
                $this->actType = $ari_data->actType;
                $this->actWay = $ari_data->actWay;
                // 返回 token 验证的 asId asLevel 账户信息...
                $this->actAs = $ari_data->actAs;
                $this->actAsTag = $ari_data->actAsTag;
                $this->actAsId = $ari_data->actAsId;
                $this->actAsLevel = $ari_data->actAsLevel;
 
                lg_debug("Token EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEnder...");
            }
        }
 
        // [Get+Post]接口[Session]授权验证 ...
        //if ($this->request->isPost()) $this->acType = "post";
        //if ($this->request->isGet()) $this->acType = "get";
 
        return Zz_Api::fo(20000, "-");
    }
 
    // 设置并加载访问账户角色等级...
    public function loadAclRls()
    {
        // 设置默认接口认证信息 ...
        $this->acChannel = "none";
        $this->acWay = "none";
        $this->acType = "none";
        $this->acAs = "G";
        $this->acAsTag = "GX";
        $this->acAsId = "G-0";
        $this->acAsLevel = "X";
        if ($this->actType) {
            // 优先使用 Token 认证信息
            $this->acChannel = "token";
            $this->acWay = $this->actWay;
            $this->acType = $this->actType;
            $this->acAs = $this->actAs;
            $this->acAsTag = $this->actAsTag;
            $this->acAsId = $this->actAsId;
            $this->acAsLevel = $this->actAsLevel;
        } else if ($this->disAccountInfo) {
            // 在 get 请求或没有 token 认证的 [unTokenRequestPathList]post 请求尝试使用 session 认证...
            $this->acChannel = "session";
            $this->acWay = $this->acsWay;
            $this->acType = $this->acsType;
            $this->acAs = $this->acsAs;
            $this->acAsTag = $this->acsAsTag;
            $this->acAsId = $this->acsAsId;
            $this->acAsLevel = $this->acsAsLevel;
        }
        //\Zz_Api::io(44333, "|#@ acInfo:[acChannel: {$this->acChannel}][acType: {$this->acType}][acWay: {$this->acWay}][acAs: {$this->acAs}][acAsId: {$this->acAsId}][acAsLevel: {$this->acAsLevel}]", $this->disAccountInfo);
 
        // 如果是 token 验证的单点登录,则尝试重建 sAccountInfo 会话信息...
        if ($this->actType == "verify" && (!isset($this->disAccountInfo["asId"]) || ($this->disAccountInfo["asId"] !== $this->acAsId))) {
            lg_info("[888][$ acAsId: {$this->acAsId}]");
            $this->session->set("sAccountInfo", ["asId" => $this->acAsId, "aInfoLevel" => $this->acAsLevel]);
            (new CommonAccountInfo())->refreshCommonAccountLoginSession($this->acAsId);
        }
 
        // 默认未登陆用户类型 Guests
        $acAs = $this->acAs;
        $acAsId = $this->acAsId;
        $acAsLevel = $this->acAsLevel;
 
        // 用户账户等级
        //$this->role = 'Guests';
        //$this->level = 'X';
 
        lg_info("[acAs: $acAs][$ acAsId: $acAsId][$ actType: {$this->actType}][$ acType: {$this->acType}][$ acChannel: {$this->acChannel}]");
        lg_info("$ sAccountInfo:");
        $sAccountInfo = $this->session->get('sAccountInfo');
        lg_info($sAccountInfo);
 
        // 如果有账号归属关系 - 包括 Guests 账号类型
        if (!in_array($acAs, $this->role_tag_list)) Zz_Api::io(44044, "unknown role [$ acAs: $acAs]...");
        $role_tag_flip_list = array_flip($this->role_tag_list); // 取数组反转结果
        $this->role = $role_tag_flip_list[$acAs];
 
        // 如果有等级归属关系 - 包括 Xal 账号等级
        if (!in_array($acAsLevel, $this->level_tag_list)) Zz_Api::io(44044, "unknown level [$ acAsLevel: {$acAsLevel}]...");
        $level_tag_flip_list = array_flip($this->level_tag_list); // 取数组反转结果
        $this->level = $level_tag_flip_list[$acAsLevel];
    }
 
    // 判断是否有接口权限...
    public function mcaAclAllowed($module, $controller, $action)
    {
        // 必须先知道当前用户角色等级...
        if (!isset($this->role) || !isset($this->level)) Zz_Api::io(44044, "|mcaAclAllowed(role,level)...");
 
        $aclAllowed = null;
        // ACL Redis Cache...
        $c_acl_rl_tag = "ACL:{$this->acAs}:{$this->acAsLevel}:{$module}:{$controller}:{$action}";
        //$this->redisDB->delete($c_acl_rl_tag);
        //Zz_Api::io(44332, "=", ["aclAllowed" => $this->redisDB->get($c_acl_rl_tag), "role" => $this->role, "level" => $this->level, "c_acl_rl_tag" => $c_acl_rl_tag]);
        //lg_debug($c_acl_rl_tag);
        if (!$this->redisDB->exists($c_acl_rl_tag)) {
            // 如果没有缓存配置,则创建判断权限,检索缓存...
 
            // role
            if (!isset($this->persistent->roleAcl)) $this->loadRoleAcl();
            $roleAclAllowed = $this->persistent->roleAcl->isAllowed($this->role, $controller, $action);
 
            // level
            if (!isset($this->persistent->levelAcl)) $this->loadLevelAcl();
            $levelAclAllowed = $this->persistent->levelAcl->isAllowed($this->level, $controller, $action);
 
            $aclAllowed = ($roleAclAllowed && $levelAclAllowed);
 
            //lg_debug("@[Role: {$this->role}][Level: {$this->level}][module: {$this->module}][controller: {$controller}][action: {$action}][aclAllowed: {$aclAllowed}][roleAclAllowed: {$roleAclAllowed}][levelAclAllowed: {$levelAclAllowed}]");
//            Zz_Api::io(40008, "[acl]", [
//                "c_acl_rl_tag" => $c_acl_rl_tag,
//                "role" => $this->role,
//                "level" => $this->level,
//                "controller" => $controller,
//                "action" => $action,
//                "aclAllowed" => $aclAllowed,
//                "roleAclAllowed" => $roleAclAllowed,
//                "levelAclAllowed" => $levelAclAllowed
//            ]);
 
            // 缓存一天
            $this->redisDB->set($c_acl_rl_tag, $aclAllowed);
            $this->redisDB->setTimeout($c_acl_rl_tag, 86400);
        } else {
            $aclAllowed = $this->redisDB->get($c_acl_rl_tag);
            //lg_debug("@[Role: {$this->role}][Level: {$this->level}][module: {$this->module}][controller: {$controller}][action: {$action}][aclAllowed: {$aclAllowed}]");
        }
 
        return $aclAllowed;
    }
 
    // 通用接口授权访问校验方法 ...
    public function authRequestInterfaceToken()
    {
//        $eaToken = $this->openSsl->createTokenInfo("tmp");
//        $this->response->setHeader("Authorization", "Bearer $eaToken");
//        $this->session->set("token", $eaToken);
 
        // 判断认证方式
        switch ($this->requestMethod) {
            case "Basic":
                $requestInfo = base64_decode($this->requestToken);
                lg_debug("requestInfo:");
                lg_debug($requestInfo);
                $requestInfo = explode(":", $requestInfo);
                lg_debug($requestInfo);
                $auth_name = $requestInfo[0];
                $auth_pass = $requestInfo[1];
 
                // 逐次检查登陆...
                $commonAccountInfo = (new Library\CommonAccountInfo())->inspectAccountInfoSerial(array("accountName" => $auth_name, "password" => md5($auth_pass)), "AND");
                if (!$commonAccountInfo) $commonAccountInfo = (new Library\CommonAccountInfo())->inspectAccountInfoSerial(array("aInfoPhone" => $auth_name, "password" => md5($auth_pass)), "AND");
                if (!$commonAccountInfo) $commonAccountInfo = (new Library\CommonAccountInfo())->inspectAccountInfoSerial(array("aInfoEmail" => $auth_name, "password" => md5($auth_pass)), "AND");
 
                // 如果检索登录失败则返回 401
                if (!$commonAccountInfo) return Zz_Api::fo(40401, "-", ["sc" => 401, "st" => "Unauthorized", "ss" => "Basic"]);
 
                // 强制刷新登录验证带用户信息的长效 [verify:token] ...
                $asId = $commonAccountInfo->asId;
                $asLevel = $commonAccountInfo->aInfoLevel;
                $eaToken = (new OpenSsl(null))->createTokenInfo("verify", $asId, $asLevel);
                // 存储 token 认证信息...
                $this->session->set("at_type", "verify");
                $this->session->set("at_way", "Bearer");
                $this->session->set("access_token", $eaToken->fo_data->token);
                // 向客户端返回最新的 [verify:token] ...
                $this->response->setHeader("Authorization", "Bearer {$eaToken->fo_data->token}");
                $this->response->sendHeaders();
 
                // 设置 token 校验类型...
                $exp = time() + 60 * 10;// 设置 Basic Token 有效期为 10 min 内...
                $as = explode("-", $asId)[0];
                $asTag = $as . $asLevel;
                return Zz_Api::fo(20000, "-", ["actType" => "verify", "actWay" => "Basic", "actAs" => $as, "actAsTag" => $asTag, "actAsId" => $asId, "actAsLevel" => $asLevel, "exp" => $exp]);
                break;
            case "Bearer":
                $deTokenInfo = $this->openSsl->deTokenInfo($this->requestToken);
                lg_debug("deTokenInfo:");
                lg_debug($deTokenInfo);
                $deToken = null;
                if ($deTokenInfo->fo_info->result) $deToken = $deTokenInfo->fo_data->deToken;
                lg_debug("deToken:");
                lg_debug($deToken);
 
                lg_debug("#Token Checker:...");
                if (!($deToken instanceof \stdClass)) lg_debug("|#|[$ deToken: $deToken]...");
                if (!$deToken || in_array($deToken, ["token-blacklisted", "token-expired", "token-exception"]))
                    return Zz_Api::fo(40401, "-", ["sc" => 401, "st" => "Unauthorized", "ss" => "Bearer|A"]);
 
                // 获取 Token 基本验证信息
                $iss = $deToken->iss;
                $asId = $sub = $deToken->sub;
                $aud = $deToken->aud;
                $iat = $deToken->iat;
                $exp = $deToken->exp;
                $jti = $deToken->jti;
                $info = $deToken->info;
                $token_type = $info->atType;
                $sid = $info->sId;
                $as = $info->as;
                $aiId = $info->aiId;
                $asLevel = $info->asLevel;
                $scope = $info->scope;
 
                // 匹配客户端 ...
                if ($sid != session_id()) return Zz_Api::fo(40401, "-", ["sc" => 401, "st" => "Unauthorized", "ss" => "Bearer|S|[$ sid: $sid|$ session_id:" . session_id() . "]"]);
 
                switch ($token_type) {
                    # 测试验证 token
                    case "test":
                        // TODO...
                        break;
                    # 一次性 token
                    case "tmp":
                        // TODO...
                        break;
                    # 30天/一次性有效 token
                    case "ovt":
                        // 加入过期黑名单...
                        $df_exp = $exp - time();
                        (new OpenSsl(null))->destroyTokenInfo($jti, $this->requestToken, $df_exp);
                        break;
                    # 已登录验证长效 token
                    case "verify":
                        // 强制续签接近过期的 Token
                        $diff_exp = $exp - time();
                        $lrt_dn = OpenSsl::$token_type_dnst[$token_type]["lrt_dn"];
                        if ($diff_exp < $lrt_dn) {
                            // 强制刷新登录验证带用户信息的长效 [verify:token] ...
                            $eaToken = (new OpenSsl(null))->refreshTokenInfo($this->requestToken);
                            // 如果续签了有效的 token ,则通过 header 发送到客户端...
                            if ($eaToken->fo_info->result) {
                                // 存储 token 认证信息...
                                $this->session->set("at_type", "verify");
                                $this->session->set("at_way", "Bearer");
                                $this->session->set("access_token", $eaToken->fo_data->token);
                                // 向客户端返回最新的 [verify:token] ...
                                $this->response->setHeader("Authorization", "Bearer {$eaToken->fo_data->token}");
                                $this->response->sendHeaders();
 
                                lg_debug("|#|authRequestInterfaceToken()|Bearer|AutoRenew|...");
                                // 过期时间续签到2小时后...
                                //$exp = time() + 60 * 60 * 2;
                            }
                        }
                        break;
                    default:
                        // TODO...
                        Zz_Api::io(40044, "Bearer Token: [$ token_type: $token_type] Error...");
                        break;
                }
 
                // 设置 token 校验类型...
                $as = explode("-", $asId)[0];
                $asTag = $as . $asLevel;
                return Zz_Api::fo(20000, "-", ["actType" => $token_type, "actWay" => "Bearer", "actAs" => $as, "actAsTag" => $asTag, "actAsId" => $asId, "actAsLevel" => $asLevel, "exp" => $exp]);
                break;
            case "QBox":
                // [鉴权类](https://developer.qiniu.com/kodo/sdk/php)
                //获取回调的body信息
                $callbackBody = file_get_contents('php://input');
                //回调的contentType
                $contentType = 'application/x-www-form-urlencoded';
                //回调的签名信息,可以验证该回调是否来自七牛
                $authorization = $_SERVER['HTTP_AUTHORIZATION'];
                //七牛回调的url,具体可以参考
                $callback_url = 'https://ap.coam.co/cloud/uploadAInfoPicture';
                $callbackUrl = $this->config->cs->callback_url . $this->action;
                // 可能有 Token 验证成功后-上传接口授权失败重定向后验证返回(401)的问题[需要开放重定向后的错误接口Token验证(Eg:/admin/common/error)]...
                $isQiniuCallback = $this->cloudStorage->cloudAuth->verifyCallback($contentType, $authorization, $callbackUrl, $callbackBody);
                // 如果七牛七牛鉴权失败则返回 401
                if (!$isQiniuCallback) return Zz_Api::fo(40401, "-", ["sc" => 401, "st" => "Unauthorized", "ss" => "QBox|_|"]);
 
                // 刷新最新用户登录信息
                $asId = null;
                $asLevel = null;
                //$sAccountInfo = $this->session->get("sAccountInfo");
                if (isset($this->disAccountInfo["asId"])) $asId = $this->disAccountInfo["asId"];
                if (isset($this->disAccountInfo["aInfoLevel"])) $asLevel = $this->disAccountInfo["aInfoLevel"];
 
                // 默认用户等级...
                $asId = "G-0";
                $asLevel = "X";
 
                // 加载 session 用户登录信息...
                $slsAi = $_POST["sessionId"];
                $slsAiTag = '_PHCR:' . $slsAi;
                lg_info("[$ _slsAiTag: $slsAiTag]");
                $upAccountSessions = $this->redisDB->get($slsAiTag);
 
                //如果存在需要更新的会话信息
                if ($upAccountSessions) {
                    //临时解压到当前用户的全局变量 $_SESSION 中
                    $_SESSION = [];//清除当前用户的 $_SESSION 防止污染转换信息
                    session_decode($upAccountSessions);
 
                    //lg_info("[$ _SESSION: ]");
                    //lg_info($_SESSION);
 
                    //$sAccountInfo = $this->session->get("sAccountInfo");
                    $sAccountInfo = $_SESSION["sAccountInfo"];
                    lg_info("[$ _sAccountInfo: ....]");
                    lg_info($sAccountInfo);
                    // 如果存在本地登录信息...
                    if ($sAccountInfo) {
                        if (isset($sAccountInfo["asId"])) $asId = $sAccountInfo["asId"];
                        if (isset($sAccountInfo["aInfoLevel"])) $asLevel = $sAccountInfo["aInfoLevel"];
                    }
 
                    //$this->redisDB->set($slsAiTag, session_encode());
                    $_SESSION = [];//清空 $_SESSION 保存的信息
                }
 
 
                // 设置 token 校验类型...
                $as = explode("-", $asId)[0];
                $asTag = $as . $asLevel;
                return Zz_Api::fo(20000, "-", ["actType" => "verify", "actWay" => "QBox", "actAs" => $as, "actAsTag" => $asTag, "actAsId" => $asId, "actAsLevel" => $asLevel, "exp" => 0]);
                break;
            default:
                return Zz_Api::fo(40444, "[$ requestMethod: {$this->requestMethod}]", ["sc" => 444, "st" => "UnverifiedError", "ss" => "_"]);
                break;
        }
 
        //return Zz_Api::fo(40444, "-", ["sc" => 444, "st" => "UnverifiedError", "ss" => "_"]);
    }
 
    // 通用接口授权访问校验方法 ...
    public function authRequestInterfaceSession()
    {
        // $this->disAccountInfo 可内部重写重定向,防止覆盖...
        if ($this->disAccountInfo) {
            // 获取并设置[Session]认证结果
            $this->acsWay = "login";
            $this->acsType = "verify";
            $asId = $this->disAccountInfo["asId"];
            $aInfoLevel = $this->disAccountInfo["aInfoLevel"];
            $as = explode("-", $asId)[0];
            $this->acsAs = $as;
            $this->acsAsTag = $as . $aInfoLevel;
            $this->acsAsId = $asId;
            $this->acsAsLevel = $aInfoLevel;
        }
    }
 
    // 设定全局登录账户认证会话信息...
    public $disAccountInfo = null;
 
    // 配置授权接口(获取token信息,可依据token认证信息完成acl接口权限认证) ...
    public $atModuleList = [];
    public $unTokenRequestPathList = [];
    public $onTokenRequestPathList = [];
    # 接口访问权限授权认证方式 ...
    public $acChannel = null; // [none|token|session]
    public $acWay = null; // [none|login|Basic|Bearer|QBox]
    public $acType = null; // [none|login|test|tmp|verify|ovt]
    public $acAs = null; // [C]
    public $acAsTag = null; // [as+level][CM]
    public $acAsId = null; // [C-*]
    public $acAsLevel = null; // [A]
    # token 认证信息 - [Post]
    public $actWay = null; // [Basic|Bearer|QBox]
    public $actType = null; // [Basic:(verify) || Bearer:(test|tmp|verify|ovt) || QBox:(verify)]
    public $actAs = null; // [C]
    public $actAsTag = null; // [CM]
    public $actAsId = null; // [C-*]
    public $actAsLevel = null; // [A]
    # session 认证信息 - [Get|Post]
    public $acsWay = null; // [none|login]
    public $acsType = null; // [none|verify]
    public $acsAs = null; // [C]
    public $acsAsTag = null; // [CM]
    public $acsAsId = null; // [C-*]
    public $acsAsLevel = null; // [A]
 
    // [Phalcon Framework的Mvc结构及启动流程(部分源码分析)- MVC事件](http://avnpc.com/pages/phalcon-mvc-process)
    //[I] dispatch:beforeDispatchLoop 分发循环开始前
    //[II] dispatch:beforeDispatch 单次分发开始前
    //[III] dispatch:beforeExecuteRoute Action执行前
    //[IV] dispatch:afterExecuteRoute Action执行后
    //[V] dispatch:beforeNotFoundAction 找不到Action
    //[VI] dispatch:beforeException 抛出异常前
    //[VII] dispatch:afterDispatch 单次分发结束
    //[VIII] dispatch:afterDispatchLoop 分发循环结束
 
    //[I] dispatch:beforeDispatchLoop 分发循环开始前
    public function beforeDispatchLoop(Event $event, Dispatcher $dispatcher)
    {
        lg_info("D[dispatch]:beforeDispatchLoop...");
        $sAccountInfo = $this->session->get('sAccountInfo');
        if ($sAccountInfo) $this->disAccountInfo = $sAccountInfo;
    }
 
    //[II] dispatch:beforeDispatch 单次分发开始前
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {
        lg_info("D[dispatch]:beforeDispatch...");
 
//        Zz_Api::io(42222, "-{$this->module}-{$this->controller}-{$this->action}-{$this->requestPathInterface}-");
 
        return true;
    }
 
    //[III] dispatch:beforeExecuteRoute Action执行前
    public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
    {
        lg_info("D[dispatch]:beforeExecuteRoute...");
    }
 
    //[IV] dispatch:afterExecuteRoute Action执行后
    public function afterExecuteRoute(Event $event, Dispatcher $dispatcher)
    {
        lg_info("D[dispatch]:afterExecuteRoute...");
 
        //输出 Json 格式数据,防止 Content-Type:text/html; charset=UTF-8 后 Chrome 难调试
        // https://forum.phalconphp.com/discussion/2038/get-rendered-view-contents-and-transform-it-into-a-json-object-o
        if ($this->request->isPost()) {
//            header('Content-Type: application/json');
            //$this->response->setHeader('Content-type', 'application/json');
            $this->response->setContentType('application/json', 'UTF-8');
            //$this->response->setContentType('Content-type', 'application/json');
        }
 
        // [afterExecuteRoute does not get called in Micro app](https://forum.phalconphp.com/discussion/1429/afterexecuteroute-does-not-get-called-in-micro-app)
//        $this->response->setContentType('application/json', 'UTF-8');
//
//        $data = $dispatcher->getReturnedValue();
//
//        if (is_array($data))
//        {
//            $this->response->setJsonContent($data);
//        } else {
//            $this->response->setStateCode(500, "Internal Server Error~~~~~~~~~~ zhangyafei ~~~");
//            $this->response->setJsonContent(array("status" => "ERROR"));
//        }
//
//        $this->response->send();
    }
 
//    //[V] dispatch:beforeNotFoundAction 找不到 Action
//    public function beforeNotFoundAction(Event $event, Dispatcher $dispatcher)
//    {
//        lg_info("D[dispatch]:beforeNotFoundAction...");
//    }
//
//    //[VI] dispatch:beforeException 抛出异常前
//    public function beforeException(Event $event, Dispatcher $dispatcher, $exception)
//    {
//        lg_info("D[dispatch]:beforeException...");
////        //处理404异常
////        if ($exception instanceof DispatchException) {
////            $dispatcher->forward(array(
////                'controller' => 'index',
////                'action' => 'errorPage'
////            ));
////            return false;
////        }
////
////        //代替控制器或者动作不存在时的路径
////        if ($event->getType() == 'beforeException') {
////            switch ($exception->getCode()) {
////                case \Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
////                case \Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
////                    $dispatcher->forward(array(
////                        'controller' => 'index',
////                        'action' => 'Error404'
////                    ));
////                    return false;
////            }
////        }
////
////        //处理其他异常
////        $dispatcher->forward(array(
////            'controller' => 'index',
////            'action' => 'Error503'
////        ));
////
////        return false;
//    }
//
//    //[VII] dispatch:afterDispatch 单次分发结束
//    public function afterDispatch(Event $event, Dispatcher $dispatcher)
//    {
//        lg_info("D[dispatch]:afterDispatch...");
//    }
//
//    //[VIII] dispatch:afterDispatchLoop 分发循环结束
//    public function afterDispatchLoop(Event $event, Dispatcher $dispatcher)
//    {
//        lg_info("D[dispatch]:afterDispatchLoop...");
//    }
}
#6Coam\App\Library\DiSecurityBase->accessRequestInterface()
/data/home/yzhang/WebCoam/Web/Applications/Utils/DiSecurity.php (794)
<?php
 
use Coam\App\Collections;
use Coam\App\Library;
use Coam\App\Models;
use Coam\App\Library\Zz_Api;
use \Phalcon\Events\Event,
    \Phalcon\Mvc\User\Plugin,
    \Phalcon\Mvc\Dispatcher,
    \Phalcon\Acl;
 
/**
 * Security
 * This is the security plugin which controls that users only have access to the modules they're assigned to
 */
class DiSecurity extends \Coam\App\Library\DiSecurityBase
{
    // 账户类型资源接口权限配置 [role]
    public $mpiRoleResources;
    public $wpiRoleResources;
    public $cliRoleResources;
    public $webRoleResources;
    public $logisticRoleResources;
    public $appRoleResources;
    public $openRoleResources;
    public $payRoleResources;
    public $imRoleResources;
    public $blogRoleResources;
    public $mailRoleResources;
 
    // 账户等级资源接口权限配置 [level]
    public $a_mpiLevelResources;
    public $c_mpiLevelResources;
    public $d_mpiLevelResources;
    public $p_mpiLevelResources;
    public $l_mpiLevelResources;
    public $e_mpiLevelResources;
    public $g_mpiLevelResources;
    public $_wpiLevelResources;
    public $g_wpiLevelResources;
    public $_cliLevelResources;
    public $g_cliLevelResources;
    public $_webLevelResources;
    public $g_webLevelResources;
    public $_logisticLevelResources;
    public $g_logisticLevelResources;
    public $_appLevelResources;
    public $g_appLevelResources;
    public $_openLevelResources;
    public $g_openLevelResources;
    public $_payLevelResources;
    public $g_payLevelResources;
    public $_imLevelResources;
    public $g_imLevelResources;
    public $_blogLevelResources;
    public $g_blogLevelResources;
    public $_mailLevelResources;
    public $g_mailLevelResources;
 
    public function __construct($dependencyInjector)
    {
        // 构建父类构造函数 ...
        parent::__construct($dependencyInjector);
 
        // 配置访问可跨的根域 ...
        $this->cross_dos = ['coam.co', 'lonal.com', 'nocs.cn', 'coopens.com', 'we-jy.com', 'zshui.org', 'zanshan.org', 'beecloudpay.com'];
 
        // 清除 Redis Di 缓存
        $this->redisDB->delete($this->redisDB->keys("ACL:*"));
        $this->redisDB->delete($this->redisDB->keys("CNML:*"));
    }
 
    // 加载权限等级...
    private function setWebAclResources()
    {
        // Web area resources
        $this->webRoleResources = $this->_webLevelResources = $this->g_webLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
                "loadInviteQrCode" => "*",
                "loadAccountQrCode" => "*",
            ),
            'serviceContent' => array("*" => '*'),
            'cooperationProcess' => array("*" => '*'),
            'cooperationDriver' => array("*" => '*'),
            'enterpriseSupport' => array("*" => '*'),
            'ourCustomers' => array("*" => '*'),
            'serviceWindow' => array("*" => '*'),
            'ourTeam' => array("*" => '*'),
            'joinUs' => array("*" => '*'),
            'ajaxLoad' => array("*" => '*'),
            //'openInterface' => array("*" =>'*'),
            'cloudStorage' => array("*" => "*"),
            'service' => array(
                "index" => "*", "loadAuthCodeVerifyImg" => "*", "verifyAuthCode" => "*", "getSecurityCode" => "*", "requestToken" => "*",
                "notify" => "*", "showUnSubscribe" => "*", "sendUnSubscribe" => "*",
                "checkAppUpdate" => "*",
                "establishAcrossSession" => "*",
            ),
        );
    }
 
    private function setLogisticAclResources()
    {
        // Logistic area resources
        $this->logisticRoleResources = $this->_logisticLevelResources = $this->g_logisticLevelResources = array(
            'index' => array("*" => '*'),
            'ajaxLoad' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
        );
    }
 
    private function setMpiAclResources()
    {
        // Mpi area resources
        # adminAccessLevel 代表显示级别 分别有 ["*":"开放所有访问权限"|"-":"关闭所有访问权限"|"A":"超级管理员权限"|"B":"二级管理员权限"|"C":"三级管理员权限"|"G":"访客权限"]
        $this->mpiRoleResources = array(
            'ajaxLoad' => array(
                "*" => "ACDPLG"
            ),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'cloud' => array(
                "*" => "*"
//                "createCloudFileUpToken" => "*", "uploadAppShareInfo" => "ACDPL", "sendNewGroupInfo" => "ACDPL", "uploadAInfoPicture" => "ACDPL",
//                "uploadCompanyLogo" => "ACDPL", "uploadTruckPicture" => "ACDPL",
//                "uploadOrderAssociationVoice" => "ACDPL", "uploadTruckOrderAssociationFile" => "ACDPL", "uploadPipelineOrderAssociationFile" => "ACDPL",
//                "uploadAuthIdentityCertifyInfo" => "ACDPL", "AuthCompanyCertifyInfo" => "ACDPL", "authTruckCertifyInfo" => "ACDPL",
//                "deleteOrderAttachedFile" => "ACDPL",
            ),
            //暂时关闭此项目下的访问控制
            'accountFund' => array(
//                "*" => "ACDPL",
                "*" => "*"
            ),
            'pay' => array(
//                "*" => "ACDPL",
                "*" => "*"
            ),
            //所有的请求都需要登陆
            'accountInfo' => array(
                "*" => "*"
//                "sendLoginAccount" => "*", "snsLogin" => "ACDPLG", "snsBind" => "ACDPL", "removeSNSBind" => "ACDPL", "commonAccountInfoRegister" => "ACDPLG", "commonAccountInfoModify" => "ACDPL",
//                "showAccountInfo" => "ACDPL", "changeAccountInfo" => "ACDPL", "NotifyServiceChange" => "ACDPL", "searchNotifyInfoWay" => "ACDPL", "showMessageNotifyInfo" => "ACDPL", "deleteMessageNotifyInfo" => "ACDPL",
//                "reSendVerifyAccountEmail" => "ACDPL", "RetrievePasswordSend" => "ACDPL", "showIdentityCertifyInfo" => "ACDPL", "applyIdentityCertifyInfo" => "ACDPL"
            ),
            'accountContact' => array(
                "*" => "ACDPL"
            ),
            'accountShare' => array(
                "*" => "ACDPLG"
            ),
            'accountSpace' => array(
                "*" => "*"
            ),
            'companyInfo' => array(
                "*" => "ACDPL"
            ),
            'accountCircle' => array(
                "*" => "*"
            ),
            'orderPipeline' => array(
                "*" => "ACDPL"
            ),
            'orderTruck' => array(
                "*" => "ACDPL"
            ),
            'orderSign' => array(
                "*" => "ACDPL"
            ),
            'orderTransfer' => array(
                "*" => "*"
            ),
            'orderDelivery' => array(
                "*" => "*"
            ),
            'service' => array(
                "*" => "*"
//                "checkAppUpdate" => "*", "searchExtractCooBankInfo" => "*",
//                "AppSoftwareDownload" => "ACDPLG", "appSoftwareUpdate" => "ACDPLG", "appSuggestionFeedback" => "ACDPLG", "softwareLicenseAndServicesAgreement" => "ACDPLG",
//                "sendPo" => "ACDPL", "myHistorySearchInfoList" => "ACDPL", "sendCooInfo" => "ACDPL", "cancelCooInfo" => "ACDPL",
//                "searchMyHsAreaList" => "ACDPL",
//                "searchSignTOrderFlowRouteChart" => "ACDPL",
//                "getAdvanceShareInfo" => "ACDPL",
//                "searchTruckOrderRoute" => "ACDPLG", "searchPipelineOrderRoute" => "ACDPLG", "pipelineDeliveryOrderSearch" => "ACDPL",
//                "searchAccountInfoQrCode" => "ACDPL", "searchTruckOrderQrCode" => "ACDPL", "customerSearchTruckOrderQrCode" => "ACDPL", "logisticsSearchTruckOrderQrCode" => "ACDPL",
//                "driverSearchTruckOrderQrCode" => "ACDPL", "searchPipelineOrderQrCode" => "ACDPL", "customerSearchPipelineOrderQrCode" => "ACDPL", "logisticsSearchPipelineOrderQrCode" => "ACDPL",
//                "driverSearchPipelineOrderQrCode" => "ACDPL",
//                "shareAccountInfo" => "ACDPLG", "shareSnsShareInfo" => "ACDPLG", "sharePOrderInfo" => "ACDPLG", "shareTOrderInfo" => "ACDPLG",
//                "referralFriendsPhoneTOrderInfo" => "ACDPL", "complaintsSuggestions" => "ACDPL"
            ),
            'parkInfo' => array(
                "*" => "*"
            ),
            'truckInfo' => array(
                "*" => "*"
            ),
            'agencyInfo' => array(
                "*" => "ACDPL"
            ),
            'deliveryInfo' => array(
                "*" => "ACDPL"
            ),
            'pipelineInfo' => array(
                "*" => "ACDPL"
            ),
        );
 
        $this->a_mpiLevelResources = $this->c_mpiLevelResources = $this->d_mpiLevelResources = $this->p_mpiLevelResources = $this->l_mpiLevelResources = $this->e_mpiLevelResources = $this->g_mpiLevelResources = array(
            'ajaxLoad' => array(
                "*" => "*"
            ),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'cloud' => array(
                "*" => "*"
//                "createCloudFileUpToken" => "*", "uploadAppShareInfo" => "*", "sendNewGroupInfo" => "*", "uploadAInfoPicture" => "*",
//                "uploadCompanyLogo" => "*", "uploadTruckPicture" => "*",
//                "uploadOrderAssociationVoice" => "*", "uploadTruckOrderAssociationFile" => "*", "uploadPipelineOrderAssociationFile" => "*",
//                "uploadAuthIdentityCertifyInfo" => "*", "uploadAuthCompanyCertifyInfo" => "*", "uploadAuthTruckCertifyInfo" => "*",
//                "deleteOrderAttachedFile" => "*",
            ),
            //暂时关闭此项目下的访问控制
            'accountFund' => array(
                "*" => "*"
            ),
            'pay' => array(
                "*" => "*"
            ),
            //所有的请求都需要登陆
            'accountInfo' => array(
                "*" => "*"
//                "sendLoginAccount" => "*", "snsLogin" => "*", "snsBind" => "*", "removeSNSBind" => "*", "commonAccountInfoRegister" => "*", "commonAccountInfoModify" => "*",
//                "showAccountInfo" => "*", "changeAccountInfo" => "*", "NotifyServiceChange" => "*", "searchNotifyInfoWay" => "*", "showMessageNotifyInfo" => "*", "deleteMessageNotifyInfo" => "*",
//                "reSendVerifyAccountEmail" => "*", "RetrievePasswordSend" => "*", "showIdentityCertifyInfo" => "*", "applyIdentityCertifyInfo" => "*"
            ),
            'accountContact' => array(
                "*" => "*"
            ),
            'accountShare' => array(
                "*" => "*"
            ),
            'accountSpace' => array(
                "*" => "*"
            ),
            'companyInfo' => array(
                "*" => "*"
            ),
            'accountCircle' => array(
                "*" => "*"
            ),
            'orderPipeline' => array(
                "*" => "*"
            ),
            'orderTruck' => array(
                "*" => "*"
            ),
            'orderSign' => array(
                "*" => "*"
            ),
            'orderTransfer' => array(
                "*" => "*"
            ),
            'orderDelivery' => array(
                "*" => "*"
            ),
            'service' => array(
                "*" => "*"
//                "checkAppUpdate" => "*", "searchExtractCooBankInfo" => "*",
//                "appSoftwareDownload" => "*", "appSoftwareUpdate" => "*", "appSuggestionFeedback" => "*", "softwareLicenseAndServicesAgreement" => "*",
//                "sendPo" => "*", "myHistorySearchInfoList" => "*", "sendCooInfo" => "*", "cancelCooInfo" => "*",
//                "searchMyHsAreaList" => "ACDPL",
//                "searchSignTOrderFlowRouteChart" => "ACDPL",
//                "getAdvanceShareInfo" => "*",
//                "searchTruckOrderRoute" => "*", "searchPipelineOrderRoute" => "*", "pipelineDeliveryOrderSearch" => "*",
//                "searchAccountInfoQrCode" => "*", "searchTruckOrderQrCode" => "*", "customerSearchTruckOrderQrCode" => "*", "logisticsSearchTruckOrderQrCode" => "*",
//                "driverSearchTruckOrderQrCode" => "*", "searchPipelineOrderQrCode" => "*", "customerSearchPipelineOrderQrCode" => "*", "logisticsSearchPipelineOrderQrCode" => "*",
//                "driverSearchPipelineOrderQrCode" => "*",
//                "shareAccountInfo" => "*", "shareSnsShareInfo" => "*", "sharePOrderInfo" => "*", "shareTOrderInfo" => "*",
//                "referralFriendsPhoneTOrderInfo" => "*", "complaintsSuggestions" => "*"
            ),
            'parkInfo' => array(
                "*" => "*"
            ),
            'truckInfo' => array(
                "*" => "*"
            ),
            'agencyInfo' => array(
                "*" => "*"
            ),
            'deliveryInfo' => array(
                "*" => "*"
            ),
            'pipelineInfo' => array(
                "*" => "*"
            ),
        );
    }
 
    private function setWpiAclResources()
    {
        // Wpi area resources
        $this->wpiRoleResources = $this->_wpiLevelResources = $this->g_wpiLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
        );
    }
 
    private function setCliAclResources()
    {
        // Cli area resources
        $this->cliRoleResources = $this->_cliLevelResources = $this->g_cliLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
        );
    }
 
    private function setOpenAclResources()
    {
        // Open area resources
        $this->openRoleResources = $this->_openLevelResources = $this->g_openLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'ajaxLoad' => array("*" => '*'),
            'open' => array("*" => '*'),
            'qqInterface' => array("*" => '*'),
            'wcInterface' => array("*" => '*'),
            'wbInterface' => array("*" => '*'),
        );
    }
 
    private function setPayAclResources()
    {
        // Pay area resources
        $this->payRoleResources = $this->_payLevelResources = $this->g_payLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'ajaxLoad' => array("*" => '*'),
            'aliPay' => array("*" => '*'),
            'bfbPay' => array("*" => '*'),
            'payWay' => array("*" => '*'),
            'pingPay' => array("*" => '*'),
            'temPay' => array("*" => '*'),
            'zsPay' => array("*" => '*'),
            'wcPay' => array("*" => '*'),
        );
    }
 
    private function setAppAclResources()
    {
        // App area resources
        $this->appRoleResources = $this->_appLevelResources = $this->g_appLevelResources = array(
            'index' => array("*" => '*'),
            'ajaxLoad' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
        );
    }
 
    private function setImAclResources()
    {
        // Im area resources
        $this->imRoleResources = $this->_imLevelResources = $this->g_imLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'ajaxLoad' => array("*" => '*'),
        );
    }
 
    private function setBlogAclResources()
    {
        // Blog area resources
        $this->blogRoleResources = $this->_blogLevelResources = $this->g_blogLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'ajaxLoad' => array("*" => '*'),
        );
    }
 
    private function setMailAclResources()
    {
        // Mail area resources
        $this->mailRoleResources = $this->_mailLevelResources = $this->g_mailLevelResources = array(
            'index' => array("*" => '*'),
            'common' => array(
                "index" => "*",
                "error" => "*",
                "sync" => "*",
            ),
            'ajaxLoad' => array("*" => '*'),
        );
    }
 
    public function loadCommonAclResources()
    {
        // 账号等级权限
        $as = explode("-", $this->acAsId)[0];
        //$asLevel = $this->acAsLevel;
        switch ($this->module) {
            case "web":
                // 加载权限等级...
                $this->setWebAclResources();
 
                $this->cMcaRoleResources = $this->webRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_webLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_webLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "logistic":
                // 加载权限等级...
                $this->setLogisticAclResources();
 
                $this->cMcaRoleResources = $this->logisticRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_logisticLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_logisticLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "mpi":
                // 加载权限等级...
                $this->setMpiAclResources();
 
                $this->cMcaRoleResources = $this->mpiRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                        $this->cMcaLevelResources = $this->a_mpiLevelResources;
                        break;
                    case "C":
                        $this->cMcaLevelResources = $this->c_mpiLevelResources;
                        break;
                    case "D":
                        $this->cMcaLevelResources = $this->d_mpiLevelResources;
                        break;
                    case "P":
                        $this->cMcaLevelResources = $this->p_mpiLevelResources;
                        break;
                    case "L":
                        $this->cMcaLevelResources = $this->l_mpiLevelResources;
                        break;
                    case "E":
                        $this->cMcaLevelResources = $this->e_mpiLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_mpiLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "wpi":
                // 加载权限等级...
                $this->setWpiAclResources();
 
                $this->cMcaRoleResources = $this->wpiRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_wpiLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_wpiLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "cli":
                // 加载权限等级...
                $this->setCliAclResources();
 
                $this->cMcaRoleResources = $this->cliRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_cliLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_cliLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "open":
                // 加载权限等级...
                $this->setOpenAclResources();
 
                $this->cMcaRoleResources = $this->openRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_openLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_openLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "pay":
                // 加载权限等级...
                $this->setPayAclResources();
 
                $this->cMcaRoleResources = $this->payRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_payLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_payLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "app":
                // 加载权限等级...
                $this->setAppAclResources();
 
                $this->cMcaRoleResources = $this->appRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_appLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_appLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "im":
                // 加载权限等级...
                $this->setImAclResources();
 
                $this->cMcaRoleResources = $this->imRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_imLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_imLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "blog":
                // 加载权限等级...
                $this->setBlogAclResources();
 
                $this->cMcaRoleResources = $this->blogRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_blogLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_blogLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            case "mail":
                // 加载权限等级...
                $this->setMailAclResources();
 
                $this->cMcaRoleResources = $this->mailRoleResources;
                // 过滤账户权限等级...
                switch ($as) {
                    case "A":
                    case "C":
                    case "D":
                    case "P":
                    case "L":
                    case "E":
                        $this->cMcaLevelResources = $this->_mailLevelResources;
                        break;
                    case "G":
                        // TODO...
                        $this->cMcaLevelResources = $this->g_mailLevelResources;
                        break;
                    default:
                        Zz_Api::io(40004, "unknown [$ module: {$this->module}] [$ as: $as]...");
                        break;
                }
                break;
            default:
                exit("unknown [$ module: {$this->module}]...");
                break;
        }
 
        // 加载 [Role|Level] Acl...
        parent::loadRoleAcl();
        parent::loadLevelAcl();
    }
 
    /**
     * This action is executed before execute any action in the application
     * 先于 beforeDispatch 触发
     */
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {
        lg_info("... [" . $_SERVER["REQUEST_URI"] . "]  .............................................................................................POST...");
        lg_debug("$ _SERVER:");
        lg_debug($_SERVER);
        lg_info("$ _POST:");
        lg_info($_POST);
        lg_info("$ _GET:");
        lg_info($_GET);
        lg_info("$ sAccountInfo:");
        $sAccountInfo = $this->session->get('sAccountInfo');
        lg_info($sAccountInfo);
        lg_info("$ disAccountInfo:");
        lg_info($this->disAccountInfo);
        lg_debug(".End............................................");
 
        //首先使用参数 $dispatcher 初始化
        $this->module = $this->router->getModuleName();
        $this->controller = $dispatcher->getControllerName();
        $this->action = $dispatcher->getActionName();
        $this->requestPathInterface = $this->module . '/' . $this->controller . '/' . $this->action;
 
        // 配置授权 module ...
        $this->atModuleList = ["app", "blog", "cli", "im", "logistic", "ma", "mail", "mpi", "open", "pay", "web", "wpi"];
        //允许公开不校验的接口
        $this->unTokenRequestPathList = [
            # [web-service]
            'web/service/loadAuthCodeVerifyImg',
            'web/service/requestToken',
            'web/service/verifyAuthCode',
            # [web-common]
            'web/common/loadInviteQrCode',
 
            # [mpi-pay]
            'mpi/pay/updatePayState',
            'mpi/pay/mPayInfo',
            'mpi/pay/pingPayCallFun',
            # [mpi-account]
            # [mpi-ajax]
            #'mpi/ajax/runAreaInfo',
            # [mpi-cloud]
            'mpi/cloud/_createCloudFileUpToken',
            //'mpi/cloud/uploadAInfoPicture',
            //'mpi/cloud/uploadTruckOrderAssociationFile',
            # [mpi-service]
            'mpi/service/checkAppUpdate',
 
            # [pay-payWay]
            'pay/payWay/pingPayCall',
            'pay/payWay/opPayCall',
            'pay/payWay/updatePayState',
 
            # [open-open]
            'open/open/curl',
 
            # [open-qqInterface]
            'open/qqInterface/webAuthConnect',
            'open/qqInterface/interface',
            'open/wbInterface/webAuthConnect',
            'open/wbInterface/interface',
            'open/wcInterface/webAuthConnect',
            'open/wcInterface/interface',
        ];
        $this->onTokenRequestPathList = ["*"];
 
        // 接口访问控制...
        $accessRiInfo = $this->accessRequestInterface();
        $fo_info = $accessRiInfo->fo_info;
        $fo_data = $accessRiInfo->fo_data;
        if (!$fo_info->result) {
            // 返回错误跨域响应头...
            $this->responseStatusCorsHeader($fo_data->sc, $fo_data->st, $fo_data->ss);
            return false;
        }
 
        //@ 可随时关闭 token 安全校验...
        // 加载接口授权认证...
        $authRi = $this->authRequestInterface();
        $fo_info = $authRi->fo_info;
        $fo_data = $authRi->fo_data;
        if (!$fo_info->result) {
            // 返回错误跨域响应头...
            $this->responseStatusCorsHeader($fo_data->sc, $fo_data->st, $fo_data->ss);
            return false;
        }
 
        // 如果没有缓存配置,则创建判断权限,检索缓存...
        $this->authRequestInterfaceSession();
 
        // 加载[Role|Level]访问角色等级...
        $this->loadAclRls();
 
        // 加载[Role|Level]访问控制...
        $this->loadCommonAclResources();
 
        // 判断接口访问控制权限...
        $this->aclAllowed = $this->mcaAclAllowed($this->module, $this->controller, $this->action);
 
        // 调用基类验证方法 ...
        return parent::beforeDispatch($event, $dispatcher);
    }
 
    /**
     * This action is executed before execute any action in the application
     * 在执行控制器/动作方法前触发.此时,调度器已经初始化了控制器并知道动作是否存在.
     */
    public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
    {
        $requestClientPlatformPlatform = $this->request->getHeader("HTTP_REQUEST_CLIENT_PLATFORM");//软件运行平台 Desktop|Android|IOS|Web
 
        //访问控制
        if ($this->aclAllowed != Acl::ALLOW) {
            // 输出权限验证调试结果...
            Zz_Api::io(40887, "", [
                "role" => $this->role,
                "controller" => $this->controller,
                "action" => $this->action,
                "aclAllowed" => $this->aclAllowed,
                "requestPathInterface" => $this->requestPathInterface,
                "cMcaRoleResources" => $this->cMcaRoleResources,
                "cMcaLevelResources" => $this->cMcaLevelResources,
            ]);
 
            //如果请求对象是桌面客户端
            if ($requestClientPlatformPlatform == "NodeDesktopClients") {
                $this->response->setHeader("AuthLoginWay", "CoamCustomerPlatformAuth");
                //Set status code
                $this->response->setStatusCode(401, "UnAuthorization");
                //Send response to the client
                $this->response->send();
            }
//            else {
//                $this->flash->error("抱歉,您暂时没有该模板的访问权限,请重新登陆-!");
//                $dispatcher->forward(
//                    array(
//                        'controller' => 'index',
//                        'action' => 'index'
//                    )
//                );
//                return true;
//            }
 
            // 跳到登录界面
            switch ($this->module) {
                case "cli":
                    $dispatcher->forward(array(
//                'namespace'  => 'Multiple\Api\Controllers',
                        "module" => $this->module,
                        'controller' => 'common',
                        'action' => 'error'
                    ));
                    break;
                case "mpi":
                    $dispatcher->forward(array(
//                'namespace'  => 'Multiple\Api\Controllers',
                        "module" => $this->module,
                        'controller' => 'common',
                        'action' => 'error'
                    ));
                    break;
                case "wpi":
                    $dispatcher->forward(array(
//                'namespace'  => 'Multiple\Api\Controllers',
                        "module" => $this->module,
                        'controller' => 'common',
                        'action' => 'error'
                    ));
                    break;
                case "web":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                case "logistic":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                case "app":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                case "mail":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                case "open":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                case "pay":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                case "im":
                    $this->flash->error("[{$this->module}]抱歉,您暂时没有该模板的访问权限,请重新登陆!");
                    $dispatcher->forward(
                        array(
                            "module" => $this->module,
                            'controller' => 'index',
                            'action' => 'index'
                        )
                    );
                    break;
                default:
                    break;
            }
 
            return false;
        } else {
            //如果是访问需要授权的页面,则进一步检查Token
            if ($this->role != "Customer" || $this->role == "Customer" /*&& $sAccountInfo["Token"] == $RequestAccessToken*/) {
                //如果请求对象是桌面客户端
                if ($requestClientPlatformPlatform == "NodeDesktopClients") {
                    $this->view->setVar("LoadWay", "NodeWebkit");
                    $this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_AFTER_TEMPLATE);
                } else {
                    $this->view->setVar("LoadWay", "WebBrowser");
                }
            } else {
                return false;
            }
        }
    }
 
    // 根据管理员权限递归检测过滤页面展示菜单
    public function af_conNavMenuLevel(&$s_menu, $i_key, &$i_menu, $s_level = "I")
    {
        $iPath = $i_menu["path"];
        // 去除首空字符并重建数组索引
        //list($m, $c, $a) = array_values(array_filter(explode("/", $iPath)));
        list($c, $a) = array_values(array_filter(explode("/", $iPath)));
        // 检测规则权限
        //$acl = $this->getAcl();
        //$allowed = $acl->isAllowed($this->role, $c, $a);
        $allowed = $this->mcaAclAllowed($this->module, $c, $a);
        $i_menu["allowed"] = $allowed;
 
        $ss_level = $s_level . "I";
        $_mLoopMenu = $ss_level . "_MenuList";
        if ($allowed && count($i_menu[$_mLoopMenu]) > 0) {
            foreach ($i_menu[$_mLoopMenu] as $ii_key => &$ii_value) {
                $ss_menu = &$s_menu[$i_key][$_mLoopMenu];
                $this->af_conNavMenuLevel($ss_menu, $ii_key, $ii_value, $ss_level);
            }
        }
 
        // 过滤掉不允许出现的菜单
        if (!$allowed) unset($s_menu[$i_key]);
    }
}
#7DiSecurity->beforeDispatch(Object(Phalcon\Events\Event), Object(Phalcon\Mvc\Dispatcher), null)
#8Phalcon\Events\Manager->fireQueue(Array([0] => Object(DiSecurity)), Object(Phalcon\Events\Event))
#9Phalcon\Events\Manager->fire(dispatch:beforeDispatch, Object(Phalcon\Mvc\Dispatcher))
#10Phalcon\Dispatcher->dispatch()
#11Phalcon\Mvc\Application->handle()
/data/home/yzhang/WebCoam/Web/public/index.php (188)
<?php
 
# 获取定义用户 web 根目录 [/data/home/yzhang]
//define('HOME_DIR', dirname(__DIR__) . "/../../../..");
define('HOME_DIR', "/data/home/yzhang");
 
// 切换开发测试环境
define('ENV', 'dev');
 
// 开启 xhprof 性能分析...
define('DEBUG_ENV', false);
 
if (!defined('ENV')) {
    error_log('Error: The application ENV constant is not set.');
    exit(1);
}
 
// 开发测试环境配置
define('DEV_ENV', 'dev');
define('TEST_ENV', 'test');
define('UPGRADE_ENV', 'upgrade');
define('DIST_ENV', 'dist');
define('DEV_ING', ENV === DEV_ENV);
define('TEST_ING', ENV === TEST_ENV);
define('UPGRADE_ING', ENV === UPGRADE_ENV);
define('DIST_ING', ENV === DIST_ENV);
 
/*
 * Environment setup
 * Different environments will require different levels of error reporting.
*/
switch (ENV) {
    case DEV_ENV:
        // 关闭支付测试环境...
        // define('DEV_PAY_ENV', false);
        if (isset($_POST["sign"]))
            define('DEV_PAY_ENV', false);
        else
            // 是否开启开发支付测试环境
            define('DEV_PAY_ENV', false);
 
        //error_reporting(E_ALL);
        //ini_set("display_errors", 1);
        (new \Phalcon\Debug)->listen();
        break;
    case TEST_ENV:
        // 关闭支付测试环境...
        // define('DEV_PAY_ENV', false);
        if (isset($_POST["sign"]))
            define('DEV_PAY_ENV', false);
        else
            // 是否开启开发支付测试环境
            define('DEV_PAY_ENV', false);
 
        //ini_set("display_errors", 0);
        //ini_set("log_errors", 1);
        //error_reporting(E_ALL);
        break;
    case UPGRADE_ENV:
        // 开启支付测试环境...
        define('DEV_PAY_ENV', false);
 
        //ini_set("display_errors", 0);
        //ini_set("log_errors", 1);
        //error_reporting(E_ALL);
        break;
    case DIST_ENV:
        // 开启支付测试环境...
        define('DEV_PAY_ENV', false);
 
        //ini_set("display_errors", 0);
        //ini_set("log_errors", 1);
        //error_reporting(E_ALL);
        break;
    default:
        error_log('Error: The application ENV constant is not set correctly.');
        exit(1);
}
 
// 开启 xhprof 性能分析...
if (DEBUG_ENV) xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
 
try {
 
    # 获取当前网站的根目录
    if (!defined('WEB_BASE_DIR')) define('WEB_BASE_DIR', dirname(__DIR__));
    if (!defined('WEB_APP_DIR')) define('WEB_APP_DIR', dirname(__DIR__) . '/Applications');
 
    // 加载主配置文件...
    include_once WEB_APP_DIR . '/Common/Config/config_common.php';
 
 
    // pay.coam.co
    //aliPay
    //require_once(APP_DIR."/plugins/Pay/ali/ali.config.php");
    //$aliPayConfig = include APP_DIR."/plugins/Pay/ali/ali.config.php";
    require_once(WEB_APP_DIR . "/Plugins/Pay/aliPay/lib/alipay_submit.class.php");
    require_once(WEB_APP_DIR . "/Plugins/Pay/aliPay/lib/alipay_notify.class.php");
 
//    //tenPay
//    require_once(WEB_APP_DIR . "/plugins/Pay/tenPay/InstantAccount/classes/RequestHandler.class.php");
//    //---------------------------------------------------------
//    //财付通即时到帐支付后台回调示例,商户按照此文档进行开发即可
//    //---------------------------------------------------------
//    require(WEB_APP_DIR . "/plugins/Pay/tenPay/InstantAccount/classes/ResponseHandler.class.php");
//    //require (COMMON_APP_DIR."/plugins/Pay/tenPay/InstantAccount/classes/RequestHandler.class.php");
//    require(WEB_APP_DIR . "/plugins/Pay/tenPay/InstantAccount/classes/client/ClientResponseHandler.class.php");
//    require(WEB_APP_DIR . "/plugins/Pay/tenPay/InstantAccount/classes/client/TenpayHttpClient.class.php");
 
 
    // *** Read auto-loader˜
    include_once WEB_APP_DIR . '/Common/loader.php';
 
    // *** Read auto-logger
    include_once WEB_APP_DIR . '/Common/logger.php';
 
    // 设置默认控制器工厂函数
    $di = new \Phalcon\DI\FactoryDefault();
 
    // *** setting di services
    include_once WEB_APP_DIR . '/Common/di-services-base.php';
    include_once WEB_APP_DIR . '/Common/di-services-common.php';
    include_once WEB_APP_DIR . '/Common/di-services-db.php';
    include_once WEB_APP_DIR . '/Common/di-services-web.php';
 
    //$application = new \Phalcon\Mvc\Application();
    //$application->setDI($di);
 
    $application = new \Phalcon\Mvc\Application($di);
    //Phalcon--debugbar第三方调试-打开500错误
 
//    $di['app'] = $application; //  Important
////    $di->set('app', $application);
//    (new Snowair\Debugbar\ServiceProvider())->start();
 
    // after start the debugbar, you can do noting but handle your app right now.
 
    // 注册模块
    $application->registerModules(
        [
            "cli" => [
                "className" => "Coam\\App\\Multiple\\Cli\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Cli/Module.php",
            ],
            "mpi" => [
                "className" => "Coam\\App\\Multiple\\Mpi\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Mpi/Module.php",
            ],
            "wpi" => [
                "className" => "Coam\\App\\Multiple\\Wpi\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Wpi/Module.php",
            ],
            "web" => [
                "className" => "Coam\\App\\Multiple\\Web\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Web/Module.php",
            ],
            "logistic" => [
                "className" => "Coam\\App\\Multiple\\Logistic\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Logistic/Module.php",
            ],
            "app" => [
                "className" => "Coam\\App\\Multiple\\App\\Module",
                "path" => WEB_APP_DIR . "/Multiple/App/Module.php",
            ],
            "open" => [
                "className" => "Coam\\App\\Multiple\\Open\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Open/Module.php",
            ],
            "pay" => [
                "className" => "Coam\\App\\Multiple\\Pay\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Pay/Module.php",
            ],
            "im" => [
                "className" => "Coam\\App\\Multiple\\Im\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Im/Module.php",
            ],
            "blog" => [
                "className" => "Coam\\App\\Multiple\\Blog\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Blog/Module.php",
            ],
            "mail" => [
                "className" => "Coam\\App\\Multiple\\Mail\\Module",
                "path" => WEB_APP_DIR . "/Multiple/Mail/Module.php",
            ],
        ]
    );
 
    echo $application->handle()->getContent();
 
} catch (\Phalcon\Exception $e) {
    echo $e->getMessage();
} catch (PDOException $e) {
    echo $e->getMessage();
}
 
# 是否开启 XhProf 调试日志 ...
if (DEBUG_ENV) Coam\App\Library\Zz_Api::endXhProfDebug();
KeyValue
_url/web/
KeyValue
USERwww-data
HOME/var/www
HTTP_ACCEPT_ENCODINGgzip
HTTP_CONNECTIONKeep-Alive
HTTP_HOSTcoam.co
HTTP_ACCEPTtext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_USER_AGENTCCBot/2.0 (https://commoncrawl.org/faq/)
REDIRECT_STATUS200
SERVER_NAMEcoam.co
SERVER_PORT443
SERVER_ADDR103.37.147.250
REMOTE_PORT50504
REMOTE_ADDR34.204.11.236
SERVER_SOFTWAREnginx/1.14.0
GATEWAY_INTERFACECGI/1.1
REQUEST_SCHEMEhttps
SERVER_PROTOCOLHTTP/1.1
DOCUMENT_ROOT/data/home/yzhang/WebCoam/Web/public/
DOCUMENT_URI/index.php
REQUEST_URI/
SCRIPT_NAME/index.php
CONTENT_LENGTH
CONTENT_TYPE
REQUEST_METHODGET
QUERY_STRING_url=/web/
HTTPSon
SCRIPT_FILENAME/data/home/yzhang/WebCoam/Web/public//index.php
FCGI_ROLERESPONDER
PHP_SELF/index.php
REQUEST_TIME_FLOAT1545205014.4373
REQUEST_TIME1545205014
#Path
0/data/home/yzhang/WebCoam/Web/public/index.php
1/data/home/yzhang/WebCoam/Web/Applications/Common/Config/config_common.php
2/data/home/yzhang/WebCoam/Web/Applications/Plugins/Pay/aliPay/lib/alipay_submit.class.php
3/data/home/yzhang/WebCoam/Web/Applications/Plugins/Pay/aliPay/lib/alipay_core.function.php
4/data/home/yzhang/WebCoam/Web/Applications/Plugins/Pay/aliPay/lib/alipay_md5.function.php
5/data/home/yzhang/WebCoam/Web/Applications/Plugins/Pay/aliPay/lib/alipay_notify.class.php
6/data/home/yzhang/WebCoam/Web/Applications/Common/loader.php
7/data/home/yzhang/WebCoam/Web/vendor/autoload.php
8/data/home/yzhang/WebCoam/Web/vendor/composer/autoload_real.php
9/data/home/yzhang/WebCoam/Web/vendor/composer/ClassLoader.php
10/data/home/yzhang/WebCoam/Web/vendor/composer/autoload_static.php
11/data/home/yzhang/WebCoam/Web/vendor/guzzlehttp/psr7/src/functions_include.php
12/data/home/yzhang/WebCoam/Web/vendor/guzzlehttp/psr7/src/functions.php
13/data/home/yzhang/WebCoam/Web/vendor/clue/stream-filter/src/functions.php
14/data/home/yzhang/WebCoam/Web/vendor/paragonie/random_compat/lib/random.php
15/data/home/yzhang/WebCoam/Web/vendor/php-http/message/src/filters.php
16/data/home/yzhang/WebCoam/Web/vendor/symfony/polyfill-mbstring/bootstrap.php
17/data/home/yzhang/WebCoam/Web/vendor/symfony/polyfill-php70/bootstrap.php
18/data/home/yzhang/WebCoam/Web/vendor/guzzlehttp/promises/src/functions_include.php
19/data/home/yzhang/WebCoam/Web/vendor/guzzlehttp/promises/src/functions.php
20/data/home/yzhang/WebCoam/Web/vendor/swiftmailer/swiftmailer/lib/swift_required.php
21/data/home/yzhang/WebCoam/Web/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php
22/data/home/yzhang/WebCoam/Web/vendor/guzzlehttp/guzzle/src/functions_include.php
23/data/home/yzhang/WebCoam/Web/vendor/guzzlehttp/guzzle/src/functions.php
24/data/home/yzhang/WebCoam/Web/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php
25/data/home/yzhang/WebCoam/Web/vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php
26/data/home/yzhang/WebCoam/Web/vendor/tinify/tinify/lib/Tinify.php
27/data/home/yzhang/WebCoam/Web/vendor/tinify/tinify/lib/Tinify/Exception.php
28/data/home/yzhang/WebCoam/Web/vendor/overtrue/wechat/src/Payment/helpers.php
29/data/home/yzhang/WebCoam/Web/vendor/qiniu/php-sdk/src/Qiniu/functions.php
30/data/home/yzhang/WebCoam/Web/vendor/qiniu/php-sdk/src/Qiniu/Config.php
31/data/home/yzhang/WebCoam/Web/vendor/xxtea/xxtea/xxtea.php
32/data/home/yzhang/WebCoam/Web/Applications/Plugins/CurlFuture/curl_future.php
33/data/home/yzhang/WebCoam/Web/Applications/Plugins/CurlFuture/inc/future.php
34/data/home/yzhang/WebCoam/Web/Applications/Plugins/CurlFuture/inc/http_future.php
35/data/home/yzhang/WebCoam/Web/Applications/Plugins/CurlFuture/inc/task.php
36/data/home/yzhang/WebCoam/Web/Applications/Plugins/CurlFuture/inc/task_manager.php
37/data/home/yzhang/WebCoam/Web/Applications/Common/logger.php
38/data/home/yzhang/WebCoam/Web/Applications/Common/di-services-base.php
39/data/home/yzhang/WebCoam/Web/Applications/Common/di-services-common.php
40/data/home/yzhang/WebCoam/Web/Applications/Common/di-services-db.php
41/data/home/yzhang/WebCoam/Web/Applications/Common/di-services-web.php
42/data/home/yzhang/WebCoam/Web/Applications/Common/routes.php
43/data/home/yzhang/WebCoam/Web/Applications/Multiple/Web/Module.php
44/data/home/yzhang/WebCoam/Web/Applications/Utils/ModuleBase.php
45/data/home/yzhang/WebCoam/Web/Applications/Utils/DiSecurity.php
46/data/home/yzhang/WebCoam/Web/Applications/Library/DiSecurityBase.php
47/data/home/yzhang/WebCoam/Web/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php
48/data/home/yzhang/WebCoam/Web/Applications/Library/DiSecurityControl.php
49/data/home/yzhang/WebCoam/Web/Applications/Collections/DiSecurityCollection.php
50/data/home/yzhang/WebCoam/Web/Applications/Collections/BaseCollection.php
51/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Mvc/MongoCollection.php
52/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Client.php
53/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Database.php
54/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Collection.php
55/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Operation/Find.php
56/data/home/yzhang/WebCoam/Web/vendor/phalcon/incubator/Library/Phalcon/Db/Adapter/MongoDB/Operation/Executable.php
Memory
Usage2097152