<?php
/**
 * This file is part of CMSGears Framework. Please view License file distributed
 * with the source code for license details.
 *
 * @link https://www.cmsgears.org/
 * @copyright Copyright (c) 2015 VulpineCode Technologies Pvt. Ltd.
 */

namespace cmsgears\newsletter\common\services\entities;

// Yii Imports
use Yii;
use yii\data\Sort;

// CMG Imports
use cmsgears\core\common\config\CoreGlobal;
use cmsgears\newsletter\common\config\NewsletterGlobal;

use cmsgears\newsletter\common\services\interfaces\entities\INewsletterService;

use cmsgears\core\common\services\base\EntityService;

use cmsgears\core\common\services\traits\base\ApprovalTrait;
use cmsgears\core\common\services\traits\base\NameTypeTrait;
use cmsgears\core\common\services\traits\base\SlugTypeTrait;

/**
 * NewsletterService provide service methods of newsletter model.
 *
 * @since 1.0.0
 */
class NewsletterService extends EntityService implements INewsletterService {

	// Variables ---------------------------------------------------

	// Globals -------------------------------

	// Constants --------------

	// Public -----------------

	public static $modelClass	= '\cmsgears\newsletter\common\models\entities\Newsletter';

	public static $typed		= true;

	public static $parentType	= NewsletterGlobal::TYPE_NEWSLETTER;

	// Protected --------------

	// Variables -----------------------------

	// Public -----------------

	// Protected --------------

	// Private ----------------

	// Traits ------------------------------------------------------

	use ApprovalTrait;
	use NameTypeTrait;
	use SlugTypeTrait;

	// Constructor and Initialisation ------------------------------

	// Instance methods --------------------------------------------

	// Yii parent classes --------------------

	// yii\base\Component -----

	// CMG interfaces ------------------------

	// CMG parent classes --------------------

	// NewsletterService ---------------------

	// Data Provider ------

	public function getPage( $config = [] ) {

		$modelClass	= static::$modelClass;
		$modelTable	= $this->getModelTable();

		$templateTable = Yii::$app->factory->get( 'templateService' )->getModelTable();

		// Sorting ----------

	    $sort = new Sort([
	        'attributes' => [
				'id' => [
					'asc' => [ "$modelTable.id" => SORT_ASC ],
					'desc' => [ "$modelTable.id" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Id'
				],
	            'template' => [
	                'asc' => [ "$templateTable.name" => SORT_ASC ],
	                'desc' => [ "$templateTable.name" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Template'
	            ],
				'name' => [
					'asc' => [ "$modelTable.name" => SORT_ASC ],
					'desc' => [ "$modelTable.name" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Name'
				],
				'slug' => [
					'asc' => [ "$modelTable.slug" => SORT_ASC ],
					'desc' => [ "$modelTable.slug" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Slug'
				],
	            'type' => [
	                'asc' => [ "$modelTable.type" => SORT_ASC ],
	                'desc' => [ "$modelTable.type" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Type'
	            ],
	            'icon' => [
	                'asc' => [ "$modelTable.icon" => SORT_ASC ],
	                'desc' => [ "$modelTable.icon" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Icon'
	            ],
				'title' => [
					'asc' => [ "$modelTable.title" => SORT_ASC ],
					'desc' => [ "$modelTable.title" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Title'
				],
	            'global' => [
	                'asc' => [ "$modelTable.global" => SORT_ASC ],
	                'desc' => [ "$modelTable.global" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Global'
	            ],
	            'status' => [
	                'asc' => [ "$modelTable.status" => SORT_ASC ],
	                'desc' => [ "$modelTable.status" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Status'
	            ],
				'cdate' => [
					'asc' => [ "$modelTable.createdAt" => SORT_ASC ],
					'desc' => [ "$modelTable.createdAt" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Created At'
				],
				'udate' => [
					'asc' => [ "$modelTable.modifiedAt" => SORT_ASC ],
					'desc' => [ "$modelTable.modifiedAt" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Updated At'
				],
	            'ldate' => [
	                'asc' => [ "$modelTable.lastSentAt" => SORT_ASC ],
	                'desc' => [ "$modelTable.lastSentAt" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Sent At'
	            ]
	        ],
			'defaultOrder' => [
				'id' => SORT_DESC
			]
	    ]);

		if( !isset( $config[ 'sort' ] ) ) {

			$config[ 'sort' ] = $sort;
		}

		// Query ------------

		if( !isset( $config[ 'query' ] ) ) {

			$config[ 'hasOne' ] = true;
		}

		// Filters ----------

		// Params
		$type	= Yii::$app->request->getQueryParam( 'type' );
		$status	= Yii::$app->request->getQueryParam( 'status' );
		$filter	= Yii::$app->request->getQueryParam( 'model' );

		// Filter - Type
		if( isset( $type ) ) {

			$config[ 'conditions' ][ "$modelTable.type" ] = $type;
		}

		// Filter - Status
		if( isset( $status ) && isset( $modelClass::$urlRevStatusMap[ $status ] ) ) {

			$config[ 'conditions' ][ "$modelTable.status" ]	= $modelClass::$urlRevStatusMap[ $status ];
		}

		// Filter - Model
		if( isset( $filter ) ) {

			switch( $filter ) {

				case 'global': {

					$config[ 'conditions' ][ "$modelTable.global" ]	= true;

					break;
				}
			}
		}

		// Searching --------

		$searchCol	= Yii::$app->request->getQueryParam( 'search' );

		if( isset( $searchCol ) ) {

			$search = [
				'name' => "$modelTable.name",
				'title' => "$modelTable.title",
				'desc' => "$modelTable.description",
				'content' => "$modelTable.content"
			];

			$config[ 'search-col' ] = $search[ $searchCol ];
		}

		// Reporting --------

		$config[ 'report-col' ]	= [
			'name' => "$modelTable.name",
			'type' => "$modelTable.type",
			'title' => "$modelTable.title",
			'desc' => "$modelTable.description",
			'global' => "$modelTable.global",
			'status' => "$modelTable.status",
			'content' => "$modelTable.content",
			'cdate' => "$modelTable.createdAt",
			'udate' => "$modelTable.modifiedAt",
			'ldate' => "$modelTable.modifiedAt"
		];

		// Result -----------

		return parent::getPage( $config );
	}

	// Read ---------------

    // Read - Models ---

    // Read - Lists ----

    // Read - Maps -----

	// Read - Others ---

	// Create -------------

	public function create( $model, $config = [] ) {

		if( empty( $model->type ) ) {

			$model->type = CoreGlobal::TYPE_DEFAULT;
		}

		return parent::create( $model, $config );
 	}

	// Update -------------

	public function update( $model, $config = [] ) {

		$admin		= isset( $config[ 'admin' ] ) ? $config[ 'admin' ] : false;
		$attributes	= isset( $config[ 'attributes' ] ) ? $config[ 'attributes' ] : [ 'templateId', 'name', 'slug', 'title', 'icon', 'description', 'content' ];

		if( $admin ) {

			$attributes[] = 'global';
			$attributes[] = 'status';
		}

		return parent::update( $model, [
			'attributes' => $attributes
		]);
 	}

	public function switchGlobal( $model, $config = [] ) {

		$global	= $model->global ? false : true;

		$model->global = $global;

		return parent::updateSelective( $model, [
			'attributes' => [ 'global' ]
		]);
 	}

	public function switchActive( $model, $config = [] ) {

		$global	= $model->global ? false : true;

		$model->global = $global;

		return parent::updateSelective( $model, [
			'attributes' => [ 'global' ]
		]);
 	}

	// Delete -------------

	// Bulk ---------------

	protected function applyBulk( $model, $column, $action, $target, $config = [] ) {

		switch( $column ) {

			case 'status': {

				switch( $action ) {

					case 'active': {

						$this->approve( $model );

						break;
					}
					case 'block': {

						$this->block( $model );

						break;
					}
				}

				break;
			}
			case 'model': {

				switch( $action ) {

					case 'global': {

						$model->global = true;

						$model->update();

						break;
					}
					case 'specific': {

						$model->global = false;

						$model->update();

						break;
					}
					case 'delete': {

						$this->delete( $model );

						break;
					}
				}

				break;
			}
		}
	}

	// Notifications ------

	// Cache --------------

	// Additional ---------

	// Static Methods ----------------------------------------------

	// CMG parent classes --------------------

	// NewsletterService ---------------------

	// Data Provider ------

	// Read ---------------

    // Read - Models ---

    // Read - Lists ----

    // Read - Maps -----

	// Read - Others ---

	// Create -------------

	// Update -------------

	// Delete -------------

}


<?php

namespace RocknRoot\StrayFw\Database;

/**
 * Useful functions.
 *
 * @abstract
 *
 * @author Nekith <nekith@errant-works.com>
 */
abstract class Helper
{
    /**
     * Apply these rules to a name :
     *    *  a sequence beginning with a lowercase letter must be followed by lowercase letters and digits
     *    *  a sequence beginning with an uppercase letter can be followed by either :
     *       *  uppercase letters and digits followed by either :
     *          *  end of the string
     *          *  an uppercase letter followed by a lowercase letter or digit
     *       *  lowercase letters or digits
     * ex : CamelCase => camel_case
     *
     * @static
     * @param  string $name model name
     * @return string codified model name
     */
    public static function codifyName(string $name) : string
    {
        $matches = array();
        preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $name, $matches);
        $ret = $matches[0];
        foreach ($ret as &$match) {
            $match = (strtoupper($match) == $match ? strtolower($match) : lcfirst($match));
        }

        return implode('_', $ret);
    }
}


<?php

namespace RocknRoot\StrayFw\Database\Postgres\Mutation;

use RocknRoot\StrayFw\Database\Database;
use RocknRoot\StrayFw\Database\Helper;

/**
 * Representation for index addition operations.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class AddIndex extends Mutation
{
    /**
     * Prepare and return according PDO statement.
     *
     * @param  Database     $database        database
     * @param  string       $modelName       model name
     * @param  string       $tableName       table real name
     * @param  array        $tableDefinition table definition
     * @param  string       $indexName       index name
     * @return \PDOStatement $statement prepared query
     */
    public static function statement(Database $database, $modelName, $tableName, array $tableDefinition, $indexName)
    {
        $indexDefinition = $tableDefinition['indexes'][$indexName];
        $indexes = array();
        foreach ($indexDefinition as $field) {
            if (isset($tableDefinition['fields'][$field]['name']) === true) {
                $indexes[] = $tableDefinition['fields'][$field]['name'];
            } else {
                $indexes[] = Helper::codifyName($modelName) . '_' . Helper::codifyName($field);
            }
        }
        $statement = $database->getMasterLink()->prepare('CREATE INDEX idx_' . $indexName . ' ON ' . $tableName . ' (' . implode(', ', $indexes) . ')');

        return $statement;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the BkstgNoticeBoardBundle package.
 * (c) Luke Bainbridge <http://www.lukebainbridge.ca/>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Bkstg\NoticeBoardBundle\EventSubscriber;

use Bkstg\CoreBundle\Event\ProductionMenuCollectionEvent;
use Bkstg\NoticeBoardBundle\BkstgNoticeBoardBundle;
use Knp\Menu\FactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class ProductionMenuSubscriber implements EventSubscriberInterface
{
    private $factory;
    private $auth;

    /**
     * Create a new production menu subscriber.
     *
     * @param FactoryInterface              $factory The menu factory service.
     * @param AuthorizationCheckerInterface $auth    The authorization checker service.
     */
    public function __construct(
        FactoryInterface $factory,
        AuthorizationCheckerInterface $auth
    ) {
        $this->factory = $factory;
        $this->auth = $auth;
    }

    /**
     * Return the events this subscriber listens for.
     *
     * @return array The subscribed events.
     */
    public static function getSubscribedEvents(): array
    {
        return [
           ProductionMenuCollectionEvent::NAME => [
               ['addNoticeBoardItem', 10],
           ],
        ];
    }

    /**
     * Add the notice board menu item.
     *
     * @param ProductionMenuCollectionEvent $event The menu collection event.
     *
     * @return void
     */
    public function addNoticeBoardItem(ProductionMenuCollectionEvent $event): void
    {
        $menu = $event->getMenu();
        $group = $event->getGroup();

        // Create notice_board menu item.
        $board = $this->factory->createItem('menu_item.notice_board', [
            'route' => 'bkstg_board_show',
            'routeParameters' => ['production_slug' => $group->getSlug()],
            'extras' => [
                'icon' => 'comment',
                'translation_domain' => BkstgNoticeBoardBundle::TRANSLATION_DOMAIN,
            ],
        ]);
        $menu->addChild($board);

        // If this user is an editor create the post and archive items.
        if ($this->auth->isGranted('GROUP_ROLE_EDITOR', $group)) {
            $posts = $this->factory->createItem('menu_item.notice_board_posts', [
                'route' => 'bkstg_board_show',
                'routeParameters' => ['production_slug' => $group->getSlug()],
                'extras' => ['translation_domain' => BkstgNoticeBoardBundle::TRANSLATION_DOMAIN],
            ]);
            $board->addChild($posts);

            $archive = $this->factory->createItem('menu_item.notice_board_archive', [
                'route' => 'bkstg_board_archive',
                'routeParameters' => ['production_slug' => $group->getSlug()],
                'extras' => ['translation_domain' => BkstgNoticeBoardBundle::TRANSLATION_DOMAIN],
            ]);
            $board->addChild($archive);
        }
    }
}


<?php
/**
 * This file is part of CMSGears Framework. Please view License file distributed
 * with the source code for license details.
 *
 * @link https://www.cmsgears.org/
 * @copyright Copyright (c) 2015 VulpineCode Technologies Pvt. Ltd.
 */

namespace cmsgears\newsletter\frontend\controllers\apix;

// Yii Imports
use Yii;
use yii\filters\VerbFilter;

// CMG Imports
use cmsgears\core\common\config\CoreGlobal;
use cmsgears\newsletter\common\config\NewsletterGlobal;

use cmsgears\newsletter\frontend\models\forms\SignUpForm;

use cmsgears\core\frontend\controllers\base\Controller;

use cmsgears\core\common\utilities\AjaxUtil;

class SiteController extends Controller {

	// Variables ---------------------------------------------------

	// Globals ----------------

	// Public -----------------

	// Protected --------------

	protected $newsletterMemberService;

	// Private ----------------

	// Constructor and Initialisation ------------------------------

 	public function init() {

        parent::init();

		$this->newsletterMemberService	= Yii::$app->factory->get( 'newsletterMemberService' );
	}

	// Instance methods --------------------------------------------

	// Yii interfaces ------------------------

	// Yii parent classes --------------------

	// yii\base\Component -----

    public function behaviors() {

        return [
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'sign-up' => [ 'post' ]
                ]
            ]
        ];
    }

	// yii\base\Controller ----

	// CMG interfaces ------------------------

	// CMG parent classes --------------------

	// SiteController ------------------------

    public function actionSignUp() {

		// Create Form Model
		$model = new SignUpForm();

		// Load and Validate Form Model
		if( $model->load( Yii::$app->request->post(), 'Newsletter' ) && $model->validate() ) {

			if( $this->newsletterMemberService->signUp( $model ) ) {

				// Trigger Ajax Success
				return AjaxUtil::generateSuccess( Yii::$app->newsletterMessage->getMessage( NewsletterGlobal::MESSAGE_NEWSLETTER_SIGNUP ) );
			}
		}

		// Generate Errors
		$errors = AjaxUtil::generateErrorMessage( $model );

		// Trigger Ajax Failure
		return AjaxUtil::generateFailure( Yii::$app->coreMessage->getMessage( CoreGlobal::ERROR_REQUEST ), $errors );
	}

}


<?php

namespace RocknRoot\StrayFw\Database;

use RocknRoot\StrayFw\Console\Request;
use RocknRoot\StrayFw\Database\Provider\Schema;

/**
 * Console actions for Database namespace.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class Console
{
    /**
     * Build data structures.
     *
     * @param Request $request current CLI request
     */
    public function build(Request $request)
    {
        if (count($request->getArgs()) != 1) {
            echo 'Wrong arguments.' . PHP_EOL . 'Usage : db/build mapping_name' . PHP_EOL;
        } else {
            $mapping = $request->getArgs()[0];
            echo 'Are you sure you want to delete all existing tables and data for mapping "' . $mapping . '" ? [y/n] : ';
            if (fgetc(STDIN) == 'y') {
                $schema = Schema::getSchema($mapping);
                $schema->build();
            }
        }
    }

    /**
     * List registered mappings.
     *
     * @param Request $request current CLI request
     */
    public function mappings(Request $request)
    {
        $table = new \cli\Table();
        $table->setHeaders([ 'Mapping', 'Database', 'Models path' ]);
        $rows = [];
        $mappings = Mapping::getMappings();
        usort($mappings, function (array $a, array $b) {
            return strcmp($a['config']['name'], $b['config']['name']);
        });
        foreach ($mappings as $mapping) {
            $rows[] = [
                $mapping['config']['name'],
                $mapping['config']['database'],
                $mapping['config']['models']['path'],
            ];
        }
        $table->setRows($rows);
        $table->display();
    }

    /**
     * Generate base models for specified mapping.
     *
     * @param Request $request current CLI request
     */
    public function generate(Request $request)
    {
        if (count($request->getArgs()) != 1) {
            echo 'Wrong arguments.' . PHP_EOL . 'Usage : db/generate mapping_name' . PHP_EOL;
        } else {
            $mapping = $request->getArgs()[0];
            $schema = Schema::getSchema($mapping);
            $schema->generateModels();
        }
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the BkstgNoticeBoardBundle package.
 * (c) Luke Bainbridge <http://www.lukebainbridge.ca/>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Bkstg\NoticeBoardBundle\Repository;

use Bkstg\CoreBundle\Entity\Production;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;

class PostRepository extends EntityRepository
{
    /**
     * Find all active posts.
     *
     * @param Production $production The production to search for.
     *
     * @return Collection
     */
    public function findAllActive(Production $production): Collection
    {
        return $this->getAllActiveQuery($production)->getResult();
    }

    /**
     * Find all inactive posts.
     *
     * @param Production $production The production to search for.
     *
     * @return Collection
     */
    public function findAllInactive(Production $production): Collection
    {
        return $this->getAllInactiveQuery($production)->getResult();
    }

    /**
     * Query to find all active posts.
     *
     * @param Production $production The production to search for.
     *
     * @return Query
     */
    public function getAllActiveQuery(Production $production): Query
    {
        $qb = $this->createQueryBuilder('p');

        return $qb
            ->join('p.groups', 'g')

            // Add conditions.
            ->andWhere($qb->expr()->eq('g', ':group'))
            ->andWhere($qb->expr()->eq('p.active', ':active'))
            ->andWhere($qb->expr()->isNull('p.parent'))
            ->andWhere($qb->expr()->orX(
                $qb->expr()->isNull('p.expiry'),
                $qb->expr()->gt('p.expiry', ':now')
            ))

            // Add parameters.
            ->setParameter('group', $production)
            ->setParameter('active', true)
            ->setParameter('now', new \DateTime())

            // Order by and get results.
            ->orderBy('p.pinned', 'DESC')
            ->addOrderBy('p.created', 'DESC')
            ->getQuery();
    }

    /**
     * Query to find all inactive posts.
     *
     * @param Production $production The production to search for.
     *
     * @return Query
     */
    public function getAllInactiveQuery(Production $production): Query
    {
        $qb = $this->createQueryBuilder('p');

        return $qb
            ->join('p.groups', 'g')

            // Add conditions.
            ->andWhere($qb->expr()->eq('g', ':group'))
            ->andWhere($qb->expr()->isNull('p.parent'))
            ->andWhere($qb->expr()->orX(
                $qb->expr()->eq('p.active', ':active'),
                $qb->expr()->lt('p.expiry', ':now')
            ))

            // Add parameters.
            ->setParameter('group', $production)
            ->setParameter('active', false)
            ->setParameter('now', new \DateTime())

            // Order by and get results.
            ->addOrderBy('p.updated', 'DESC')
            ->getQuery();
    }
}


<?php

namespace RocknRoot\StrayFw;

/**
 * General class for user's controllers storage.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class Controllers
{
    /**
     * Existing controllers.
     *
     * @static
     * @var object[]
     */
    protected static $controllers = array();

    /**
     * Get a controller, creating one if it doesn't exist already.
     *
     * @static
     * @param string $class controller class with namespace
     * @return object controller
     */
    public static function get(string $class)
    {
        if (isset(self::$controllers[$class]) === false) {
            self::$controllers[$class] = new $class();
        }

        return self::$controllers[$class];
    }
}


<?php
/**
 * This file is part of CMSGears Framework. Please view License file distributed
 * with the source code for license details.
 *
 * @link https://www.cmsgears.org/
 * @copyright Copyright (c) 2015 VulpineCode Technologies Pvt. Ltd.
 */

namespace cmsgears\icons\components;

// Yii Imports
use yii\base\Component;

// CMG Imports
use cmsgears\files\components\FileManager;

class IconManager extends Component {

	// Variables ---------------------------------------------------

	// Globals ----------------

	// Public -----------------

	public $iconSets = [ 'cmti' => true, 'fa' => true ];

	// Protected --------------

	// Private ----------------

	// Constructor and Initialisation ------------------------------

	// Instance methods --------------------------------------------

	// Yii interfaces ------------------------

	// Yii parent classes --------------------

	// CMG interfaces ------------------------

	// CMG parent classes --------------------

	// IconManager ---------------------------

	/**
	 * By default it returns the icons from CMGTools IconLib library. The parameter defaultSet
	 * can be changed or it can be overriden to change default behaviour.
	 *
	 * @param type $fileType
	 * @return string
	 */
	public function getFileIcon( $fileType, $iconLib = 'cmti' ) {

		switch( $iconLib ) {

			case 'cmti': {

				return $this->getCmtiFileIcon( $fileType );
			}
			case 'fa': {

				return $this->getFaFileIcon( $fileType );
			}
		}
	}

	/**
	 * Return the icon corresponding to given file type from CMT IconLib library.
	 *
	 * @param string $fileType
	 * @return string
	 */
	protected function getCmtiFileIcon( $fileType ) {

		switch( $fileType ) {

			case FileManager::FILE_TYPE_IMAGE: {

				return 'cmti-image';
			}
			case FileManager::FILE_TYPE_VIDEO: {

				return 'cmti-file-video';
			}
			case FileManager::FILE_TYPE_AUDIO: {

				return 'cmti-file-audio';
			}
			case FileManager::FILE_TYPE_DOCUMENT: {

				return 'cmti-document';
			}
			case FileManager::FILE_TYPE_COMPRESSED: {

				return 'cmti-file-zip';
			}
		}
	}

	/**
	 * Return the icon corresponding to given file type from Font Awesome library.
	 *
	 * @param string $fileType
	 * @return string
	 */
	protected function getFaFileIcon( $fileType ) {

		switch( $fileType ) {

			case FileManager::FILE_TYPE_IMAGE: {

				return 'fa-file-image';
			}
			case FileManager::FILE_TYPE_VIDEO: {

				return 'fa-file-video';
			}
			case FileManager::FILE_TYPE_AUDIO: {

				return 'fa-file-audio';
			}
			case FileManager::FILE_TYPE_DOCUMENT: {

				return 'fa-file';
			}
			case FileManager::FILE_TYPE_COMPRESSED: {

				return 'fa-file-archive';
			}
		}
	}

}


<?php declare(strict_types=1);

namespace RPQ\Server\Process;

use Amp\ByteStream\Message;
use Amp\Loop;
use Amp\Process\Process;
use Amp\Promise\wait;
use Exception;
use Monolog\Logger;
use RPQ\Client;
use RPQ\Queue;
use RPQ\Server\Process\Handler\JobHandler;
use RPQ\Server\Process\Handler\SignalHandler;
use Throwable;

/**
 * Dispatcher polls Redis for new jobs, and then starts the requested job
 * @package RPQ\Queue
 */
final class Dispatcher
{
    /**
     * @var Client $client
     */
    private $client;

    /*
     * @var array $config
     */
    private $config;

    /**
     * @var array $args
     */
    private $args = [
        'configFile' => ''
    ];

    /**
     * @var array $process
     */
    private $processes = [];

    /**
     * @var Logger $logger
     */
    private $logger;

    /**
     * @var Queue $queue
     */
    private $queue;

    /**
     * @var SignalHandler $signalHandler
     */
    private $signalHandler;

    /**
     * @var JobHandler $jobHandler
     */
    private $jobHandler;

    /**
     * @var bool $isRunning;
     */
    private $isRunning = true;

    /**
     * @return Logger
     */
    public function getLogger()
    {
        return $this->logger;
    }

    /**
     * @return Client
     */
    public function getClient()
    {
        return $this->client;
    }

    /**
     * @return array
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * @return Queue
     */
    public function getQueue()
    {
        return $this->queue;
    }

    /**
     * @return array
     */
    public function getArgs()
    {
        return $this->args;
    }

    /**
     * Constructor
     * @param Client $client
     * @param Logger $this->logger
     * @param array $config
     * @param array $args
     */
    public function __construct(Client $client, Logger $logger, Queue $queue, array $config = [], array $args = [])
    {
        if (\function_exists('pcntl_async_signals')) {
            \pcntl_async_signals(true);
        }

        $this->client = $client;
        $this->config = $config;
        $this->args = $args;
        $this->logger = $logger;
        $this->queue = $queue;
        $this->signalHandler = new SignalHandler($this);
        $this->jobHandler = new JobHandler(
            $this->client,
            $this->logger,
            $this->queue
        );
    }

    /**
     * Retrieves a list of running processes
     * @return array
     */
    public function getProcesses()
    {
        return $this->processes;
    }

    /**
     * Sets the running status
     * @param boolean $status
     */
    public function setIsRunning($status = true)
    {
        $this->isRunning = $status;
    }

    /**
     * Starts an Amp\Loop event loop and begins polling Redis for new jobs
     * @return void
     */
    public function start()
    {
        Loop::run(function () {
            $this->logger->info(sprintf("RPQ is now started, and is listening for new jobs every %d ms", $this->config['poll_interval']), [
                'queue' => $this->queue->getName()
            ]);

            $this->setIsRunning(false);
            Loop::repeat($this->config['poll_interval'], function ($watcherId, $callback) {
                if (!$this->isRunning) {
                    return;
                }

                // Pushes scheduled jobs onto the main queue
                $this->queue->rescheduleJobs();

                // Only allow `max_jobs` to run
                if (count($this->processes) === $this->config['max_jobs']) {
                    return;
                }

                // ZPOP a job from the priority queue
                $job = $this->queue->pop();

                if ($job !== null) {
                    // Spawn a new worker process to handle the job
                    $command = sprintf(
                        'exec %s %s --jobId=%s --name=%s',
                        ($this->config['process']['script'] ?? $_SERVER["SCRIPT_FILENAME"]),
                        $this->config['process']['command'],
                        $job->getId(),
                        $this->queue->getName()
                    );

                    if ($this->config['process']['config'] === true) {
                        $command .= " --config={$this->args['configFile']}";
                    }

                    $process = new Process($command);
                    $process->start();

                    // Grab the PID and push it onto the process stack
                    $pid = yield $process->getPid();
                    $this->logger->info('Started worker', [
                        'pid' => $pid,
                        'command' => $command,
                        'id' => $job->getId(),
                        'queue' => $this->queue->getName()
                    ]);

                    $this->processes[$pid] = [
                        'process' => $process,
                        'id' => $job->getId()
                    ];

                    // Stream any output from the worker in realtime
                    $stream = $process->getStdout();
                    while ($chunk = yield $stream->read()) {
                        $this->logger->info($chunk, [
                            'pid' => $pid,
                            'jobId' => $job->getId(),
                            'queue' => $this->queue->getName()
                        ]);
                    }

                    // When the job is done, it will emit an exit status code
                    $code = yield $process->join();

                    $this->jobHandler->exit(
                        $job->getId(),
                        $pid,
                        $code,
                        false,
                        $this->config['failed_job_backoff_time']
                    );

                    unset($this->processes[$pid]);
                }
            });

            $this->registerSignals();
        });
    }

    /**
     * Registers signals
     *
     * @return void
     */
    private function registerSignals()
    {
        foreach ($this->signalHandler->getSignals() as $signal) {
            $this->logger->debug('Registering signal', [
                'signal' => $signal
            ]);

            Loop::onSignal($signal, function ($signalId, $signal) {
                $promise = $this->signalHandler->handle($signal);
                $promise->onResolve(function ($error, $value) {
                    if ($error) {
                        $this->logger->info($error->getMessage());
                        return;
                    }

                    if ($value === null) {
                        $this->logger->info('Signal successfully handled. RPQ is now shutting down. Goodbye.');
                        exit(0);
                    }
                });
            });
        }

        $this->setIsRunning(true);
    }
}


<?php

namespace RocknRoot\StrayFw\Database\Postgres;

use RocknRoot\StrayFw\Database\Provider\Database as ProviderDatabase;

/**
 * PostgreSQL database helper.
 * User code shouldn't use this class directly.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class Database implements ProviderDatabase
{
    /**
     * Get DSN string for PDO according to specified info.
     *
     * @param  array  $info database info
     * @return string DSN string
     */
    public function getDsn(array $info) : string
    {
        $dsn = 'pgsql:host=';
        $dsn .= (isset($info['host']) === true ? $info['host'] : 'localhost') . ';';
        if (isset($info['port']) === true) {
            $dsn .= 'port=' . $info['port'] . ';';
        }
        $dsn .= 'dbname=' . $info['name'] . ';';

        return $dsn;
    }

    /**
     * Begin transaction if applicable.
     *
     * @param mixed $link link info
     * @return bool true if successful
     */
    public function beginTransaction($link) : bool
    {
        return $link->beginTransaction();
    }

    /**
     * Commit the current transaction if applicable.
     *
     * @param mixed $link link info
     * @return bool true if successful
     */
    public function commit($link) : bool
    {
        return $link->commit();
    }

    /**
     * Roll back the current transaction if applicable.
     *
     * @param mixed $link link info
     * @return bool true if successful
     */
    public function rollBack($link) : bool
    {
        return $link->rollBack();
    }

    /**
     * Create a new save point if applicable.
     *
     * @param mixed $link link info
     * @param string $name save point name
     * @return bool true if successful
     */
    public function savePoint($link, string $name) : bool
    {
        return $link->exec('SAVEPOINT ' . $name);
    }

    /**
     * Release a save point if applicable.
     *
     * @param mixed $link link info
     * @param string $name save point name
     * @return bool true if successful
     */
    public function releaseSavePoint($link, string $name) : bool
    {
        return $link->exec('RELEASE SAVEPOINT ' . $name);
    }

    /**
     * Roll back a save point if applicable.
     *
     * @param mixed $link link info
     * @param string $name save point name
     * @return bool true if successful
     */
    public function rollBackSavePoint($link, string $name) : bool
    {
        return $link->exec('ROLLBACK TO SAVEPOINT ' . $name);
    }
}


<?php

namespace RocknRoot\StrayFw\Database;

use RuntimeException;
use RocknRoot\StrayFw\Config;
use RocknRoot\StrayFw\Console\Request;
use RocknRoot\StrayFw\Exception\FileNotReadable;
use RocknRoot\StrayFw\Exception\FileNotWritable;

/**
 * Console actions for migration related operations.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class Migration
{
    /**
     * Create a new migration.
     *
     * @param Request $req current CLI request
     * @throws FileNotReadable if can't find schema file
     * @throws FileNotWritable if can't copy schema file
     */
    public function create(Request $req)
    {
        if (count($req->getArgs()) != 2) {
            echo 'Wrong arguments.' . PHP_EOL . 'Usage : db/migration/create mapping_name migration_name' . PHP_EOL;
        } else {
            $mappingName = $req->getArgs()[0];
            $mapping = Mapping::get($mappingName);
            $name = ucfirst($req->getArgs()[1]);
            if ($this->write($mapping, $mappingName, $name) === true) {
                $path = rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
                $path .= $name . DIRECTORY_SEPARATOR . 'schema.yml';
                if (file_exists($mapping['config']['schema']) === false) {
                    throw new FileNotReadable('can\'t find "' . $mapping['schema'] . '"');
                }
                if (copy($mapping['config']['schema'], $path) === false) {
                    throw new FileNotWritable('can\'t copy "' . $mapping['schema'] . '" to "' . $path . '"');
                }
                $migrations = [];
                $path = rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'migrations.yml';
                if (file_exists($path) === true) {
                    $migrations = Config::get($path);
                }
                $migrations[] = [
                    'name' => $name,
                    'timestamp' => time(),
                ];
                Config::set($path, $migrations);
                echo 'Migration "' . $name . '" created.' . PHP_EOL;
            }
        }
    }

    /**
     * Generate code for migration.
     *
     * @param Request $req current CLI request
     * @throws FileNotReadable if can't find migrate
     */
    public function generate(Request $req)
    {
        if (count($req->getArgs()) != 2) {
            echo 'Wrong arguments.' . PHP_EOL . 'Usage : db/migration/create mapping_name migration_name' . PHP_EOL;
        } else {
            $mappingName = $req->getArgs()[0];
            $mapping = Mapping::get($mappingName);
            $name = ucfirst($req->getArgs()[1]);
            $path = rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
            $path .= $name . DIRECTORY_SEPARATOR . $name . '.php';
            if (file_exists($path) === false) {
                throw new FileNotReadable('can\'t find migration at "' . $path . '"');
            }
            $cl = '\\' . ltrim(rtrim($mapping['config']['provider'], '\\'), '\\') . '\\Migration::generate';
            if (is_callable($cl) === false) {
                throw new RuntimeException(
                    'Migration generate method is not callable on configured provider!'
                );
            }
            $res = call_user_func($cl, $mapping, $mappingName, $name);
            $this->write($mapping, $mappingName, $name, $res['up'], $res['down'], $res['import']);
            echo 'Migration "' . $name . '" generated.' . PHP_EOL;
            echo 'This is an automatic generation, please validate or rewrite parts of the migration.' . PHP_EOL;
            echo 'File is there:' . PHP_EOL;
            echo $path . PHP_EOL;
        }
    }

    /**
     * Run migration code for a mapping.
     *
     * @param Request $req current CLI request
     */
    public function migrate(Request $req)
    {
        if (count($req->getArgs()) != 1) {
            echo 'Wrong arguments.' . PHP_EOL . 'Usage : db/migration/migrate mapping_name' . PHP_EOL;
        } else {
            $mappingName = $req->getArgs()[0];
            $mapping = Mapping::get($mappingName);
            $cl = '\\' . ltrim(rtrim($mapping['config']['provider'], '\\'), '\\') . '\\Migration::migrate';
            if (is_callable($cl) === false) {
                throw new RuntimeException(
                    'Migration migrate method is not callable on configured provider!'
                );
            }
            call_user_func($cl, $mapping);
            echo 'Migrate - Done' . PHP_EOL;
        }
    }

    /**
     * Rollback last migration for a mapping.
     *
     * @param Request $req current CLI request
     */
    public function rollback(Request $req)
    {
        if (count($req->getArgs()) != 1) {
            echo 'Wrong arguments.' . PHP_EOL . 'Usage : db/migration/rollback mapping_name' . PHP_EOL;
        } else {
            $mappingName = $req->getArgs()[0];
            $mapping = Mapping::get($mappingName);
            $cl = '\\' . ltrim(rtrim($mapping['config']['provider'], '\\'), '\\') . '\\Migration::rollback';
            if (is_callable($cl) === false) {
                throw new RuntimeException(
                    'Migration rollback method is not callable on configured provider!'
                );
            }
            call_user_func($cl, $mapping);
            echo 'Rollback - Done' . PHP_EOL;
        }
    }

    /**
     * Write migration code to file.
     *
     * @param  array           $mapping     mapping definition
     * @param  string          $mappingName mapping name
     * @param  string          $name        migration name
     * @param  array           $up          up code
     * @param  array           $down        down code
     * @param  array           $import      used classes in migration code
     * @throws FileNotWritable if can't mkdir
     * @throws FileNotWritable if can't open file with write permission
     * @throws FileNotWritable if can't write to file
     */
    private function write(array $mapping, string $mappingName, string $name, array $up = [], array $down = [], array $import = [])
    {
        $path = rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        $path .= $name . DIRECTORY_SEPARATOR;
        if (file_exists($path . $name . '.php') === true) {
            echo 'A migration with this name already exists. Do you want to overwrite it ? [y/n] : ';
            if (fgetc(STDIN) != 'y') {
                return false;
            }
        }
        if (is_dir($path) === false) {
            if (mkdir($path) === false) {
                throw new FileNotWritable('can\'t mkdir "' . $path . '"');
            }
        }
        $path .= $name . '.php';
        $file = fopen($path, 'w+');
        if ($file === false) {
            throw new FileNotWritable('can\'t open "' . $path . '" with write permission');
        }
        $content = "<?php\n\nnamespace " . ltrim(rtrim($mapping['config']['migrations']['namespace'], '\\'), '\\') . '\\' . $name . ";\n\nuse " . ltrim(rtrim($mapping['config']['provider'], '\\'), '\\') . '\\Migration;' . PHP_EOL;
        if (count($import) >= 1) {
            $content .= 'use ' . ltrim(rtrim($mapping['config']['provider'], '\\'), '\\') . '\\Mutation\\{';
            $content .= implode(', ', $import) . "};\n";
        }
        $up = implode('', array_map(function (string $a) {
            return '        ' . $a . '->execute();' . PHP_EOL;
        }, $up));
        $down = implode('', array_map(function (string $a) {
            return '        ' . $a . '->execute();' . PHP_EOL;
        }, $down));
        var_dump($up);
        $content .= "\nclass " . $name . " extends Migration\n{\n";
        $content .= '    const NAME = \'' . $name . "';\n\n";
        $content .= "    public function getMappingName() : string\n    {\n        return '" . $mappingName . "';\n    }\n\n";
        $content .= "    public function up()\n    {\n" . $up . "    }\n\n";
        $content .= "    public function down()\n    {\n" . $down . "    }\n";
        $content .= "}";
        if (fwrite($file, $content) === false) {
            throw new FileNotWritable('can\'t write in "' . $path . '"');
        }
        fclose($file);

        return true;
    }
}


<?php

namespace RocknRoot\StrayFw\Database\Postgres;

use RocknRoot\StrayFw\Database\Helper;
use RocknRoot\StrayFw\Database\Postgres\Query\Delete;
use RocknRoot\StrayFw\Database\Postgres\Query\Insert;
use RocknRoot\StrayFw\Database\Postgres\Query\Select;
use RocknRoot\StrayFw\Database\Postgres\Query\Update;
use RocknRoot\StrayFw\Database\Provider\Model as ProviderModel;

/**
 * Model representation class for PostgreSQL tables.
 *
 * @abstract
 *
 * @author Nekith <nekith@errant-works.com>
 */
abstract class Model extends ProviderModel
{
    /**
     * Aliases of modified columns values.
     *
     * @var array<string, scalar|null>
     */
    protected $modified;

    /**
     * Save the model. Delete if deletionFlag is true.
     *
     * @return bool true if successfully saved
     */
    public function save() : bool
    {
        $status = false;
        if ($this->new === false) {
            if ($this->deletionFlag === true) {
                $status = $this->delete();
            } elseif (count($this->modified) > 0) {
                $updateQuery = new Update($this->getDatabaseName());
                $updateQuery->update($this->getTableName());

                $where = array();
                foreach ($this->getPrimary() as $primary) {
                    $field = $this->{'field' . ucfirst($primary)};
                    $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($primary)));
                    $where[$realName] = ':primary' . ucfirst($primary);
                    $updateQuery->bind('primary' . ucfirst($primary), $field['value']);
                }
                $updateQuery->where($where);

                $set = array();
                foreach ($this->modified as $key => $value) {
                    if ($value === true) {
                        $field = $this->{'field' . ucfirst($key)};
                        $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                        $set[$realName] = ':field' . ucfirst($key);
                        $updateQuery->bind(':field' . ucfirst($key), $field['value']);
                    }
                }
                $updateQuery->set($set);

                $this->modified = array();

                $status = $updateQuery->execute();
            }
        } else {
            if ($this->deletionFlag === false) {
                $insertQuery = new Insert($this->getDatabaseName());
                $insertQuery->into($this->getTableName());

                $returning = array();
                foreach ($this->getPrimary() as $primary) {
                    $field = $this->{'field' . ucfirst($primary)};
                    $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($primary)));
                    $returning[] = $realName;
                }
                $insertQuery->returning($returning);

                $values = array();
                foreach ($this->getAllFieldsAliases() as $name) {
                    $field = $this->{'field' . ucfirst($name)};
                    if (isset($field['value']) === true) {
                        $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($name)));
                        $values[$realName] = ':field' . ucfirst($name);
                        $insertQuery->bind('field' . ucfirst($name), $field['value']);
                    }
                }
                $insertQuery->values($values);

                $status = $insertQuery->execute();

                if ($status === true) {
                    $this->modified = array();
                    $rows = $insertQuery->getStatement()->fetch(\PDO::FETCH_ASSOC);
                    $imax = count($rows);
                    for ($i = 0; $i < $imax; $i++) {
                        $field = &$this->{'field' . ucfirst($this->getPrimary()[$i])};
                        $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($this->getPrimary()[$i])));
                        $realName = substr($realName, stripos($realName, '.') + 1);
                        $field['value'] = $rows[$realName];
                    }
                    $this->new = false;
                }
            }
        }

        return $status;
    }

    /**
     * If not new, delete the model.
     *
     * @return bool true if successfully deleted
     */
    public function delete() : bool
    {
        $status = false;
        if ($this->new === false) {
            $deleteQuery = new Delete($this->getDatabaseName());
            $deleteQuery->from($this->getTableName());
            $where = array();
            foreach ($this->getPrimary() as $primary) {
                $field = $this->{'field' . ucfirst($primary)};
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($primary)));
                $where[$realName] = ':primary' . ucfirst($primary);
                $deleteQuery->bind('primary' . ucfirst($primary), $field['value']);
            }
            $deleteQuery->where($where);

            $status = $deleteQuery->execute();
        }

        return $status;
    }

    /**
     * Get field values as associative array (alias => value).
     *
     * @return array values
     */
    public function toArray() : array
    {
        $values = array();
        foreach ($this->getAllFieldsAliases() as $name) {
            $field = $this->{'field' . ucfirst($name)};
            $values[$name] = $field['value'];
        }

        return $values;
    }

    /**
     * Get field values as associative array (real names => value).
     *
     * @return array values
     */
    public function toRealNamesArray() : array
    {
        $values = array();
        foreach ($this->getAllFieldsAliases() as $name) {
            $field = $this->{'field' . ucfirst($name)};
            $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($name)));
            $values[$realName] = $field['value'];
        }

        return $values;
    }

    /**
     * Fetch one entity satisfying the specified conditions.
     *
     * @param  array $conditions where conditions
     * @param  array $orderBy    order clause
     * @param  bool  $critical   if true, will be executed on write server
     * @return Model|false model instance
     */
    public static function fetchEntity(array $conditions, array $orderBy = null, bool $critical = false)
    {
        $entity = new static();
        $selectQuery = new Select($entity->getDatabaseName(), $critical);
        $selectQuery->select($entity->getAllFieldsRealNames());
        $selectQuery->from($entity->getTableName());
        if (count($conditions) > 0) {
            $where = array();
            foreach ($conditions as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $where[$realName] = ':where' . ucfirst($key);
                $selectQuery->bind('where' . ucfirst($key), $value);
            }
            $selectQuery->where($where);
        }
        if (is_array($orderBy) && count($orderBy) > 0) {
            $orders = array();
            foreach ($orderBy as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $orders[$realName] = strtoupper(ucfirst($value));
            }
            $selectQuery->orderBy($orders);
        }
        $selectQuery->limit(1);
        if ($selectQuery->execute() === false) {
            return false;
        }
        $data = $selectQuery->fetch();
        if ($data === false) {
            return false;
        }

        return new static($data);
    }

    /**
     * Fetch one row satisfying the specified conditions.
     *
     * @param  array $conditions where conditions
     * @param  array $orderBy    order clause
     * @param  bool  $critical   if true, will be executed on write server
     * @return array|false row data
     */
    public static function fetchArray(array $conditions, array $orderBy = null, bool $critical = false)
    {
        $entity = new static();
        $selectQuery = new Select($entity->getDatabaseName(), $critical);
        $selectQuery->select($entity->getAllFieldsRealNames());
        $selectQuery->from($entity->getTableName());
        if (count($conditions) > 0) {
            $where = array();
            foreach ($conditions as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $where[$realName] = ':where' . ucfirst($key);
                $selectQuery->bind('where' . ucfirst($key), $value);
            }
            $selectQuery->where($where);
        }
        if (is_array($orderBy) && count($orderBy) > 0) {
            $orders = array();
            foreach ($orderBy as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $orders[$realName] = strtoupper(ucfirst($value));
            }
            $selectQuery->orderBy($orders);
        }
        $selectQuery->limit(1);
        if ($selectQuery->execute() === false) {
            return false;
        }
        $data = $selectQuery->fetch();
        if (is_array($data) === false) {
            return false;
        }

        return $data;
    }

    /**
     * Fetch all entities satisfying the specified conditions.
     *
     * @param  array $conditions where conditions
     * @param  array $orderBy    order clause
     * @param  bool  $critical   if true, will be executed on write server
     * @return array|false rows data
     */
    public static function fetchEntities(array $conditions, array $orderBy = null, bool $critical = false)
    {
        $entity = new static();
        $res = static::fetchArrays($conditions, $orderBy, $critical);
        $selectQuery = new Select($entity->getDatabaseName(), $critical);
        $selectQuery->select($entity->getAllFieldsRealNames());
        $selectQuery->from($entity->getTableName());
        if (count($conditions) > 0) {
            $where = array();
            foreach ($conditions as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $where[$realName] = ':where' . ucfirst($key);
                $selectQuery->bind('where' . ucfirst($key), $value);
            }
            $selectQuery->where($where);
        }
        if (is_array($orderBy) && count($orderBy) > 0) {
            $orders = array();
            foreach ($orderBy as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $orders[$realName] = strtoupper(ucfirst($value));
            }
            $selectQuery->orderBy($orders);
        }
        if ($selectQuery->execute() === false) {
            return false;
        }
        $res = $selectQuery->fetchAll();
        if (is_array($res) === false) {
            return false;
        }
        $data = [];
        foreach ($res as $r) {
            $data[] = new static($r);
        }

        return $data;
    }

    /**
     * Fetch all rows satisfying the specified conditions.
     *
     * @param  array $conditions where conditions
     * @param  array $orderBy    order clause
     * @param  bool  $critical   if true, will be executed on write server
     * @return array|false rows data
     */
    public static function fetchArrays(array $conditions, array $orderBy = null, bool $critical = false)
    {
        $entity = new static();
        $selectQuery = new Select($entity->getDatabaseName(), $critical);
        $selectQuery->select((array) array_combine($entity->getAllFieldsAliases(), $entity->getAllFieldsRealNames()));
        $selectQuery->from($entity->getTableName());
        if (count($conditions) > 0) {
            $where = array();
            foreach ($conditions as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $where[$realName] = ':where' . ucfirst($key);
                $selectQuery->bind('where' . ucfirst($key), $value);
            }
            $selectQuery->where($where);
        }
        if (is_array($orderBy) && count($orderBy) > 0) {
            $orders = array();
            foreach ($orderBy as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $orders[$realName] = strtoupper(ucfirst($value));
            }
            $selectQuery->orderBy($orders);
        }
        if ($selectQuery->execute() === false) {
            return false;
        }
        $data = $selectQuery->fetchAll();
        if (is_array($data) === false) {
            return false;
        }

        return $data;
    }

    /**
     * Count rows satisfying the specified conditions.
     *
     * @param  array $conditions where conditions
     * @param  bool  $critical   if true, will be executed on write server
     * @return int|false   number of rows or false on error
     */
    public static function countRows(array $conditions, bool $critical = false)
    {
        $entity = new static();
        $selectQuery = new Select($entity->getDatabaseName(), $critical);
        $selectQuery->select([ 'count' => 'COUNT(*)' ]);
        $selectQuery->from($entity->getTableName());
        if (count($conditions) > 0) {
            $where = array();
            foreach ($conditions as $key => $value) {
                $realName = constant(get_called_class() . '::FIELD_' . strtoupper(Helper::codifyName($key)));
                $where[$realName] = ':where' . ucfirst($key);
                $selectQuery->bind('where' . ucfirst($key), $value);
            }
            $selectQuery->where($where);
        }
        if ($selectQuery->execute() === false) {
            return false;
        }
        $data = $selectQuery->fetch();
        if ($data === false) {
            return false;
        }

        return $data['count'];
    }

    /**
     * Get database's name.
     *
     * @abstract
     * @return string database's name
     */
    abstract public function getDatabaseName() : string;

    /**
     * Get table's name.
     *
     * @abstract
     * @return string table's name
     */
    abstract public function getTableName() : string;

    /**
     * Get primary fields' names.
     *
     * @abstract
     * @return array primary fields' names
     */
    abstract public function getPrimary() : array;

    /**
     * Get all fields' names.
     *
     * @abstract
     * @return array all fields' names
     */
    abstract public function getAllFieldsRealNames() : array;

    /**
     * Get all fields' aliases.
     *
     * @abstract
     * @return array all fields' aliases
     */
    abstract public function getAllFieldsAliases() : array;
}


<?php

declare(strict_types=1);

/*
 * This file is part of the BkstgNoticeBoardBundle package.
 * (c) Luke Bainbridge <http://www.lukebainbridge.ca/>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Bkstg\NoticeBoardBundle\Timeline\EventSubscriber;

use Bkstg\TimelineBundle\Event\TimelineLinkEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class PostLinkSubscriber implements EventSubscriberInterface
{
    private $url_generator;

    /**
     * Create a new post link subscriber.
     *
     * @param UrlGeneratorInterface $url_generator The url generator service.
     */
    public function __construct(UrlGeneratorInterface $url_generator)
    {
        $this->url_generator = $url_generator;
    }

    /**
     * Return the events this subscriber listens for.
     *
     * @return array The subscribed events.
     */
    public static function getSubscribedEvents()
    {
        return [
            TimelineLinkEvent::NAME => [
                ['setPostLink', 0],
            ],
        ];
    }

    /**
     * Set the post link on the timeline.
     *
     * @param TimelineLinkEvent $event The timeline link event.
     *
     * @return void
     */
    public function setPostLink(TimelineLinkEvent $event): void
    {
        $action = $event->getAction();

        if (!in_array($action->getVerb(), ['post', 'reply'])) {
            return;
        }

        $production = $action->getComponent('indirectComplement')->getData();
        $post = $action->getComponent('directComplement')->getData();
        $event->setLink($this->url_generator->generate('bkstg_board_show', [
            'production_slug' => $production->getSlug(),
            '_fragment' => 'post-' . $post->getId(),
        ]));
    }
}


<?php

namespace RocknRoot\StrayFw\Database\Postgres\Mutation;

use RocknRoot\StrayFw\Database\Database;

/**
 * Representation for foreign key deletion operations.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class DeleteForeignKey extends Mutation
{
    /**
     * Prepare and return according PDO statement.
     *
     * @param  Database     $database database
     * @param  string       $table    table name
     * @param  string       $key      foreign key name
     * @return \PDOStatement $statement prepared query
     */
    public static function statement(Database $database, $table, $key)
    {
        $statement = $database->getMasterLink()->prepare('ALTER TABLE ' . $table . ' DROP CONSTRAINT IF EXISTS fk_' . $key);

        return $statement;
    }
}


<?php

/**
 * MvcCore
 *
 * This source file is subject to the BSD 3 License
 * For the full copyright and license information, please view
 * the LICENSE.md file that are distributed with this source code.
 *
 * @copyright	Copyright (c) 2016 Tom Flídr (https://github.com/mvccore/mvccore)
 * @license		https://mvccore.github.io/docs/mvccore/4.0.0/LICENCE.md
 */

namespace MvcCore\Ext\Debugs\Tracys;

/**
 * Responsibility - after all scripts are done, display all used PHP files in it's own `Tracy` debug bar.
 * - Generate for all used PHP files their file debug links.
 * - If any used file is used by tracy debug bar - mark this file in debug panel by different css colour.
 */
class IncludePanel implements \Tracy\IBarPanel
{
	/**
	 * All used PHP files list by current request.
	 * @var string[]
	 */
	protected static $files = [];

	/**
	 * Used PHP files count except files used by `Tracy` extension.
	 * @var mixed
	 */
	protected static $appFilesCount = 0;

	/**
	 * All used PHP files count.
	 * @var int
	 */
	protected static $allFilesCount = 0;

	/**
	 * Get unique `Tracy` debug bar panel id.
	 * @return string
	 */
	public function getId() {
		return 'include-panel';
	}

	/**
	 * Return rendered debug panel heading HTML code displayed all time in `Tracy` debug  bar.
	 * @return string
	 */
	public function getTab() {
		static::completeFilesCountsAndEditorLinks();
		return '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADtUExURQAAAANAWAULDjxIVExOUQsKCA4nMANOaxYyPQJCWg0ZHgJQbQYMDyM8UzVrnmhXHl1eYm5uaHx8gQolLVJfaz9PXm2TtrOPIH1wMV5TJ29kLQI8UtWtJkhKK3FmKtOvLAQ1SARQbTMqHIyMjISEicLCz6zS9GdyeN/f6vf3+Vai6qOjymtrrb3Z83y37o3A8Obt9TaI03dxWdDY3ZmannJyr1BQoXeAhMPH3dTU37291rXG183j+Nbo+WWQuWqk2mCo6om+72Ko61JRQnN+hUczHJGepiBNd2ROJzhaeJijpF1dpkdHm5iYxe7u8lzeC4UAAAAkdFJOUwACQpD4JkALx2Z+RU/8/dr9+f28q6H982I0Snb1y/Pvn1zx+/LnWboAAAC0SURBVBjTbczVFoJAFIXhoUtQ7M4RKUUBBbs73v9xZAD1xu/u/GuvAwCC4QSBgx8mO18oKx77hlx/uFQGIv8ZUXmlr1gb8UAmopBYb63BbnQ8uXK0oSRd10d72fG8DINCqX6Wrhfb0TSNRaHcSGba9s1XVT8MxWqSI1NDYzKZPV9BoAq1FgOhen+YhqmiBS1goAOn5nhmjKfhjwBMdyOfkHZ7AZJlm3EgIZKqMPENaC4kgD/e1akVKEqC52oAAAAASUVORK5CYII="/>'
			. self::$appFilesCount;
	}

	/**
	 * Return rendered debug panel content window HTML code.
	 * @return string
	 */
	public function getPanel() {
		self::completeFilesCountsAndEditorLinks();
		$usedFilesListCode = join("", static::$files);
		return ''
			.'
'
				.'
Included app files: '.static::$appFilesCount.' (all: '.static::$allFilesCount.')
'
				.'
'
					.$usedFilesListCode
				.'
'
			.'
';
	}

	/**
	 * Complete final used PHP files list as list of HTML codes with editor links.
	 * @return void
	 */
	protected static function completeFilesCountsAndEditorLinks () {
		if (!static::$files) {
			$rawList = get_included_files();
			$list = [];
			$docRoot = str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']);
			$docRootLength = mb_strlen($docRoot);
			$tracyFileDetectionSubstr = '/tracy';
			foreach ($rawList as & $file) {
				$file = str_replace('\\', '/', $file);
				$text = mb_substr($file, $docRootLength);
				$tracyFile = mb_stripos($text, $tracyFileDetectionSubstr) !== FALSE;
				if (!$tracyFile) static::$appFilesCount += 1;
				static::$allFilesCount += 1;
				$href = \Tracy\Helpers::editorUri($file, 1);
				$list[] = '<nobr>'.$text.'</nobr>
';
			}
			static::$files = & $list;
		}
	}
}


<?php

declare(strict_types=1);

/*
 * This file is part of the BkstgNoticeBoardBundle package.
 * (c) Luke Bainbridge <http://www.lukebainbridge.ca/>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Bkstg\NoticeBoardBundle\Controller;

use Bkstg\CoreBundle\Controller\Controller;
use Bkstg\CoreBundle\Entity\Production;
use Bkstg\NoticeBoardBundle\BkstgNoticeBoardBundle;
use Bkstg\NoticeBoardBundle\Entity\Post;
use Bkstg\NoticeBoardBundle\Form\PostType;
use Bkstg\NoticeBoardBundle\Form\ReplyType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class PostController extends Controller
{
    /**
     * Create a new post.
     *
     * @param string                        $production_slug The production slug.
     * @param Request                       $request         The incoming request.
     * @param TokenStorageInterface         $token           The token storage service.
     * @param AuthorizationCheckerInterface $auth            The authorization checker service.
     *
     * @throws NotFoundHttpException When the production is not found.
     * @throws AccessDeniedException When the user is not a member of the production.
     *
     * @return Response
     */
    public function createAction(
        string $production_slug,
        Request $request,
        TokenStorageInterface $token,
        AuthorizationCheckerInterface $auth
    ): Response {
        // Lookup the production by production_slug.
        $production_repo = $this->em->getRepository(Production::class);
        if (null === $production = $production_repo->findOneBy(['slug' => $production_slug])) {
            throw new NotFoundHttpException();
        }

        // Check permissions for this action.
        if (!$auth->isGranted('GROUP_ROLE_USER', $production)) {
            throw new AccessDeniedException();
        }

        // Get some basic information about the user.
        $user = $token->getToken()->getUser();

        // Create a new post.
        $post = new Post();
        $post->setActive(true);
        $post->setPinned(false);
        $post->setAuthor($user->getUsername());
        $post->addGroup($production);

        // This post is a reply.
        if ($request->query->has('reply-to')) {
            // Make sure the parent post is valid.
            $repo = $this->em->getRepository(Post::class);
            if (null === $parent = $repo->findOneBy(['id' => $request->query->get('reply-to')])) {
                throw new NotFoundHttpException();
            }

            // Must be a member of the same group.
            if (!$parent->getGroups()->contains($production)) {
                throw new AccessDeniedException();
            }

            // Parent must not be a child.
            if (null !== $parent->getParent()) {
                throw new AccessDeniedException();
            }
            $post->setParent($parent);

            // This is a reply, use the basic reply form.
            $form = $this->form->create(ReplyType::class, $post);
        } else {
            // This is a new post, use the post form.
            $form = $this->form->create(PostType::class, $post);
        }

        // Handle the form.
        $form->handleRequest($request);

        // Form is submitted and valid.
        if ($form->isSubmitted() && $form->isValid()) {
            // Persist the post.
            $this->em->persist($post);
            $this->em->flush();

            // Set success message and redirect.
            $this->session->getFlashBag()->add(
                'success',
                $this->translator->trans('post.created', [], BkstgNoticeBoardBundle::TRANSLATION_DOMAIN)
            );

            return new RedirectResponse($this->url_generator->generate(
                'bkstg_board_show',
                ['production_slug' => $production->getSlug()]
            ));
        }

        // Render the form.
        return new Response($this->templating->render('@BkstgNoticeBoard/Post/create.html.twig', [
            'form' => $form->createView(),
            'post' => $post,
            'production' => $production,
        ]));
    }

    /**
     * Update a post.
     *
     * @param string                        $production_slug The production slug.
     * @param int                           $id              The id of the post.
     * @param Request                       $request         The incoming request.
     * @param TokenStorageInterface         $token           The token storage service.
     * @param AuthorizationCheckerInterface $auth            The authorization checker service.
     *
     * @throws AccessDeniedException When the user is not a member of the production.
     *
     * @return Response
     */
    public function updateAction(
        string $production_slug,
        int $id,
        Request $request,
        TokenStorageInterface $token,
        AuthorizationCheckerInterface $auth
    ): Response {
        // Lookup the post and production.
        list($post, $production) = $this->lookupEntity(Post::class, $id, $production_slug);

        // Check permissions for this action.
        if (!$auth->isGranted('edit', $post)) {
            throw new AccessDeniedException();
        }

        // Get some basic information about the user.
        $user = $token->getToken()->getUser();

        // Create a new form for the post and handle.
        if (null !== $post->getParent()) {
            $form = $this->form->create(ReplyType::class, $post);
        } else {
            $form = $this->form->create(PostType::class, $post);
        }

        // Handle the form submission.
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // Flush entity manager, set success message and redirect.
            $this->em->flush();
            $this->session->getFlashBag()->add(
                'success',
                $this->translator->trans('post.updated', [], BkstgNoticeBoardBundle::TRANSLATION_DOMAIN)
            );

            return new RedirectResponse($this->url_generator->generate(
                'bkstg_board_show',
                ['production_slug' => $production->getSlug()]
            ));
        }

        // Render the form.
        return new Response($this->templating->render('@BkstgNoticeBoard/Post/update.html.twig', [
            'form' => $form->createView(),
            'post' => $post,
            'production' => $production,
        ]));
    }

    /**
     * Delete a post.
     *
     * @param string                        $production_slug The production slug.
     * @param int                           $id              The id of the post.
     * @param Request                       $request         The incoming request.
     * @param TokenStorageInterface         $token           The token storage service.
     * @param AuthorizationCheckerInterface $auth            The authorization checker service.
     *
     * @throws AccessDeniedException When the user is not a member of the production.
     *
     * @return Response
     */
    public function deleteAction(
        string $production_slug,
        int $id,
        Request $request,
        TokenStorageInterface $token,
        AuthorizationCheckerInterface $auth
    ): Response {
        // Lookup the post and production.
        list($post, $production) = $this->lookupEntity(Post::class, $id, $production_slug);

        // Check permissions for this action.
        if (!$auth->isGranted('edit', $post)) {
            throw new AccessDeniedException();
        }

        // Create an empty form to submit.
        $form = $this->form->createBuilder()->getForm();
        $form->handleRequest($request);

        // Delete the post.
        if ($form->isSubmitted() && $form->isValid()) {
            $this->em->remove($post);
            $this->em->flush();

            // Set success message and redirect.
            $this->session->getFlashBag()->add(
                'success',
                $this->translator->trans('post.deleted', [], BkstgNoticeBoardBundle::TRANSLATION_DOMAIN)
            );

            return new RedirectResponse($this->url_generator->generate(
                'bkstg_board_show',
                ['production_slug' => $production->getSlug()]
            ));
        }

        // Render the form.
        return new Response($this->templating->render('@BkstgNoticeBoard/Post/delete.html.twig', [
            'production' => $production,
            'post' => $post,
            'form' => $form->createView(),
        ]));
    }
}


<?php

namespace RocknRoot\StrayFw\Render;

/**
 * JSON render class.
 * In development environment, JSON is pretty printed.
 *
 * @author Nekith <nekith@errant-works.com>
 */
class RenderJson implements RenderInterface
{
    /**
     * Return the generated display.
     *
     * @param  array  $args        view args
     * @param  bool   $prettyPrint force pretty print parameter
     * @return string content
     */
    public function render(array $args, bool $prettyPrint = null)
    {
        header('Content-type: application/json');
        if ((constant('STRAY_ENV') === 'development' && $prettyPrint !== false) || $prettyPrint === true) {
            return (string) json_encode($args, JSON_PRETTY_PRINT);
        }

        return (string) json_encode($args);
    }
}


<?php
/**
 * This file is part of CMSGears Framework. Please view License file distributed
 * with the source code for license details.
 *
 * @link https://www.cmsgears.org/
 * @copyright Copyright (c) 2015 VulpineCode Technologies Pvt. Ltd.
 */

namespace cmsgears\newsletter\admin\controllers\apix;

// Yii Imports
use Yii;
use yii\filters\VerbFilter;

// CMG Imports
use cmsgears\newsletter\common\config\NewsletterGlobal;

/**
 * NewsletterController provide actions specific to Newsletter.
 *
 * @since 1.0.0
 */
class NewsletterController extends \cmsgears\core\admin\controllers\base\Controller {

	// Variables ---------------------------------------------------

	// Globals ----------------

	// Public -----------------

	// Protected --------------

	// Private ----------------

	// Constructor and Initialisation ------------------------------

	public function init() {

		parent::init();

		// Permission
		$this->crudPermission = NewsletterGlobal::PERM_NEWSLETTER_ADMIN;

		// Services
		$this->modelService = Yii::$app->factory->get( 'newsletterService' );
	}

	// Instance methods --------------------------------------------

	// Yii interfaces ------------------------

	// Yii parent classes --------------------

	// yii\base\Component -----

	public function behaviors() {

		return [
			'rbac' => [
				'class' => Yii::$app->core->getRbacFilterClass(),
				'actions' => [
					'auto-search' => [ 'permission' => $this->crudPermission ],
					'bulk' => [ 'permission' => $this->crudPermission ],
					'delete' => [ 'permission' => $this->crudPermission ]
				]
			],
			'verbs' => [
				'class' => VerbFilter::class,
				'actions' => [
					'auto-search' => [ 'post' ],
					'bulk' => [ 'post' ],
					'delete' => [ 'post' ]
				]
			]
		];
	}

	// yii\base\Controller ----

	public function actions() {

		return [
			'auto-search' => [ 'class' => 'cmsgears\core\common\actions\content\AutoSearch' ],
			'bulk' => [ 'class' => 'cmsgears\core\common\actions\grid\Bulk' ],
			'delete' => [ 'class' => 'cmsgears\core\common\actions\grid\Delete' ]
		];
	}

	// CMG interfaces ------------------------

	// CMG parent classes --------------------

	// NewsletterController ------------------

}


<?php

namespace Railken\Amethyst\Schemas;

use Illuminate\Support\Facades\Config;
use Railken\Amethyst\Attributes as AmethystAttributes;
use Railken\Amethyst\Managers\AddressManager;
use Railken\Lem\Attributes;
use Railken\Lem\Schema;

class LegalEntitySchema extends Schema
{
    /**
     * Get all the attributes.
     *
     * @var array
     */
    public function getAttributes()
    {
        return [
            Attributes\IdAttribute::make(),
            Attributes\TextAttribute::make('name')
                ->setRequired(true),
            Attributes\LongTextAttribute::make('notes'),
            AmethystAttributes\TaxonomyAttribute::make('type_id', Config::get('amethyst.legal-entity.taxonomies.0.name'))
                ->setRelationName('type')
                ->setRequired(true),
            AmethystAttributes\CountryAttribute::make('country'),
            Attributes\BelongsToAttribute::make('registered_office_address_id')
                ->setRelationName('registered_office_address')
                ->setRelationManager(AddressManager::class),
            Attributes\CreatedAtAttribute::make(),
            Attributes\UpdatedAtAttribute::make(),
            Attributes\DeletedAtAttribute::make(),
        ];
    }
}


<?php
/**
 * This file is part of CMSGears Framework. Please view License file distributed
 * with the source code for license details.
 *
 * @link https://www.cmsgears.org/
 * @copyright Copyright (c) 2015 VulpineCode Technologies Pvt. Ltd.
 */

namespace cmsgears\newsletter\common\services\entities;

// Yii Imports
use Yii;
use yii\data\Sort;

// CMG Imports
use cmsgears\newsletter\common\services\interfaces\entities\INewsletterMemberService;
use cmsgears\newsletter\common\services\interfaces\mappers\INewsletterListService;

use cmsgears\core\common\services\base\EntityService;

/**
 * NewsletterMemberService provide service methods of newsletter member.
 *
 * @since 1.0.0
 */
class NewsletterMemberService extends EntityService implements INewsletterMemberService {

	// Variables ---------------------------------------------------

	// Globals -------------------------------

	// Constants --------------

	// Public -----------------

	public static $modelClass = '\cmsgears\newsletter\common\models\entities\NewsletterMember';

	// Protected --------------

	// Variables -----------------------------

	// Public -----------------

	// Protected --------------

	protected $newsletterListService;

	// Private ----------------

	// Traits ------------------------------------------------------

	// Constructor and Initialisation ------------------------------

    public function __construct( INewsletterListService $newsletterListService, $config = [] ) {

		$this->newsletterListService = $newsletterListService;

        parent::__construct( $config );
    }

	// Instance methods --------------------------------------------

	// Yii parent classes --------------------

	// yii\base\Component -----

	// CMG interfaces ------------------------

	// CMG parent classes --------------------

	// NewsletterMemberService ---------------

	// Data Provider ------

	public function getPage( $config = [] ) {

		$modelClass	= static::$modelClass;
		$modelTable	= $this->getModelTable();

		$userTable = Yii::$app->factory->get( 'userService' )->getModelTable();

		// Sorting ----------

	    $sort = new Sort([
	        'attributes' => [
				'id' => [
					'asc' => [ "$modelTable.id" => SORT_ASC ],
					'desc' => [ "$modelTable.id" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Id'
				],
	            'user' => [
					'asc' => [ "$userTable.name" => SORT_ASC ],
					'desc' => [ "$userTable.name" => SORT_DESC ],
					'default' => SORT_DESC,
	                'label' => 'User'
	            ],
				'name' => [
					'asc' => [ "$modelTable.name" => SORT_ASC ],
					'desc' => [ "$modelTable.name" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Name'
				],
	            'email' => [
	                'asc' => [ "$modelTable.email" => SORT_ASC ],
	                'desc' => [ "$modelTable.email" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Email'
	            ],
	            'active' => [
	                'asc' => [ "$modelTable.active" => SORT_ASC ],
	                'desc' => [ "$modelTable.active" => SORT_DESC ],
	                'default' => SORT_DESC,
	                'label' => 'Active'
	            ],
				'cdate' => [
					'asc' => [ "$modelTable.createdAt" => SORT_ASC ],
					'desc' => [ "$modelTable.createdAt" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Created At'
				],
				'udate' => [
					'asc' => [ "$modelTable.modifiedAt" => SORT_ASC ],
					'desc' => [ "$modelTable.modifiedAt" => SORT_DESC ],
					'default' => SORT_DESC,
					'label' => 'Updated At'
				]
	        ]
	    ]);

		if( !isset( $config[ 'sort' ] ) ) {

			$config[ 'sort' ] = $sort;
		}

		// Query ------------

		if( !isset( $config[ 'query' ] ) ) {

			$config[ 'hasOne' ] = true;
		}

		// Filters ----------

		// Filter - Model
		$filter	= Yii::$app->request->getQueryParam( 'model' );

		if( isset( $filter ) ) {

			switch( $filter ) {

				case 'active': {

					$config[ 'conditions' ][ "$modelTable.active" ]	= true;

					break;
				}
			}
		}

		// Searching --------

		$searchCol	= Yii::$app->request->getQueryParam( 'search' );

		if( isset( $searchCol ) ) {

			$search = [
				'name' => "$modelTable.name",
				'email' => "$modelTable.email"
			];

			$config[ 'search-col' ] = $search[ $searchCol ];
		}

		// Reporting --------

		$config[ 'report-col' ]	= [
			'name' => "$modelTable.name",
			'email' => "$modelTable.email",
			'active' => "$modelTable.active"
		];

		// Result -----------

		return parent::getPage( $config );
	}

	// Read ---------------

    // Read - Models ---

	public function getByEmail( $email ) {

		$modelClass	= static::$modelClass;

		return $modelClass::findByEmail( $email );
	}

    // Read - Lists ----

	public function searchByName( $name, $config = [] ) {

		$modelClass	= static::$modelClass;
		$modelTable	= $this->getModelTable();

		$config[ 'query' ]		= $modelClass::queryWithHasOne();
		$config[ 'columns' ]	= [ "$modelTable.id", "$modelTable.name", "$modelTable.email" ];
		$config[ 'array' ]		= isset( $config[ 'array' ] ) ? $config[ 'array' ] : false;

		$config[ 'query' ]->andWhere( "$modelTable.name like '$name%'" );

		$models = static::searchModels( $config );
		$result	= [];

		foreach( $models as $model ) {

			$result[] = [ 'id' => $model->id, 'name' => "$model->name, $model->email" ];
		}

		return $result;
	}

    // Read - Maps -----

	// Read - Others ---

	// Create -------------

	public function create( $model, $config = [] ) {

		if( empty( $model->siteId ) ) {

			$model->siteId = Yii::$app->core->site->id;
		}

		return parent::create( $model, $config );
 	}

 	public function createByParams( $params = [], $config = [] ) {

		$member	= $this->getByEmail( $params[ 'email' ] );

		if( isset( $member ) ) {

			return $member;
		}

		return parent::createByParams( $params, $config );
 	}

	public function signUp( $signUpForm ) {

		$member	= $this->getByEmail( $signUpForm->email );

		// Create Newsletter Member
		if( !isset( $member ) ) {

			$member	= $this->getModelObject();

			if( empty( $member->siteId ) ) {

				$member->siteId = Yii::$app->core->siteId;
			}

			$member->email 	= $signUpForm->email;
			$member->name 	= $signUpForm->name;
			$member->active = true;

			$member->save();
		}

		// Add to specific and selected mailing list
		if( isset( $signUpForm->newsletterId ) ) {

			$this->newsletterListService->createByParams( [ 'newsletterId' => $signUpForm->newsletterId, 'memberId' => $member->id, 'active' => true ] );
		}

		return $member;
	}

	// Update -------------

	public function update( $model, $config = [] ) {

		return parent::update( $model, [
			'attributes' => [ 'email', 'name', 'active' ]
		]);
 	}

	public function updateByParams( $params = [], $config = [] ) {

		$member	= $this->getByEmail( $params[ 'email' ] );

		if( isset( $member ) ) {

			return parent::update( $member, [
				'attributes' => [ 'name', 'active' ]
			]);
		}

		return $this->createByParams( $params, $config );
	}

	public function toggleActive( $model, $config = [] ) {

		$global	= $model->global ? false : true;

		$model->global = $global;

		return parent::updateSelective( $model, [
			'attributes' => [ 'global' ]
		]);
 	}

	// Delete -------------

	public function deleteByEmail( $email, $config = [] ) {

		$member	= $this->getByEmail( $email );

		if( isset( $member ) ) {

			$modelClass	= static::$modelClass;

			// Delete from mailing list
			Yii::$app->factory->get( 'newsletterListService' )->deleteByMemberId( $member->id );

			// Delete member
			return $modelClass::deleteByEmail( $email );
		}

		return false;
	}

	// Bulk ---------------

	protected function applyBulk( $model, $column, $action, $target, $config = [] ) {

		switch( $column ) {

			case 'model': {

				switch( $action ) {

					case 'active': {

						$model->active = true;

						$model->update();

						break;
					}
					case 'inactive': {

						$model->active = false;

						$model->update();

						break;
					}
					case 'delete': {

						$this->delete( $model );

						break;
					}
				}

				break;
			}
		}
	}

	// Notifications ------

	// Cache --------------

	// Additional ---------

	// Static Methods ----------------------------------------------

	// CMG parent classes --------------------

	// NewsletterMemberService ---------------

	// Data Provider ------

	// Read ---------------

    // Read - Models ---

    // Read - Lists ----

    // Read - Maps -----

	// Read - Others ---

	// Create -------------

	// Update -------------

	// Delete -------------

}


<?php declare(strict_types=1);

namespace RPQ\Server\Process\Handler;

use Monolog\Logger;
use RPQ\Client;
use RPQ\Exception\JobNotFoundException;
use RPQ\Queue;

final class JobHandler
{
    /**
     * @var Client $client
     */
    private $client;

    /**
     * @var Logger $this->logger
     */
    private $logger;

    /**
     * @var Queue $queue
     */
    private $queue;

    /**
     * Constructor
     *
     * @param Client $client
     * @param Logger $logger
     * @param string $this->queue
     */
    public function __construct(Client $client, Logger $logger, Queue $queue)
    {
        $this->client = $client;
        $this->logger = $logger;
        $this->queue = $queue;
    }

    /**
     * Handles process end, and requeuing if necessary
     *
     * @param string $id
     * @param int $pid
     * @param int $code
     * @param bool $forceRetry
     * @param int $queueBackoffTime
     * @return void
     */
    public function exit($id, $pid, $code, $forceRetry = false, $queueBackoffTime = null)
    {
        $this->logger->info('Job ended', [
            'exitCode' => $code,
            'pid' => $pid,
            'jobId' => $id,
            'queue' => $this->queue->getName()
        ]);

        $hash = explode(':', $id);
        $jobId = $hash[count($hash) - 1];
        try {
            $job = $this->queue->getJob($jobId);
        } catch (JobNotFoundException $e) {
            $this->logger->info('Unable to process job exit code or retry status. Job data unavailable', [
                'exitCode' => $code,
                'pid' => $pid,
                'jobId' => $job->getId(),
                'queue' => $this->queue->getName()
            ]);
            return true;
        }

        // If the job ended successfully, remove the data from redis
        if ($code === 0) {
            $this->logger->info('Job succeeded and is now complete', [
                'exitCode' => $code,
                'pid' => $pid,
                'jobId' => $job->getId(),
                'queue' => $this->queue->getName()
            ]);

            return $job->end();
        } else {
            $retry = $job->getRetry();

            // If force retry was specified, force this job to retry indefinitely
            if ($forceRetry === true) {
                $retry = true;
            }

            if ($retry === true || $retry > 0) {
                $this->logger->info('Rescheduling job', [
                    'exitCode' => $code,
                    'pid' => $pid,
                    'jobId' => $job->getId(),
                    'queue' => $this->queue->getName(),
                    'time' => \time() + $queueBackoffTime ?? 0
                ]);

                // If a retry is specified, repush the job back onto the queue with the same Job ID
                return $job->retry($queueBackoffTime);
            } else {
                $this->logger->info('Job failed', [
                    'exitCode' => $code,
                    'pid' => $pid,
                    'jobId' => $job->getId(),
                    'queue' => $this->queue->getName()
                ]);

                return $job->fail();
            }
        }

        return;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the BkstgNoticeBoardBundle package.
 * (c) Luke Bainbridge <http://www.lukebainbridge.ca/>
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Bkstg\NoticeBoardBundle\Timeline\Spread;

use Bkstg\CoreBundle\User\UserInterface;
use Bkstg\NoticeBoardBundle\Entity\Post;
use Spy\Timeline\Model\ActionInterface;
use Spy\Timeline\Spread\Entry\EntryCollection;
use Spy\Timeline\Spread\Entry\EntryUnaware;
use Spy\Timeline\Spread\SpreadInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class ReplySpread implements SpreadInterface
{
    private $user_provider;

    /**
     * Create a new reply spread.
     *
     * @param UserProviderInterface $user_provider The user provider service.
     */
    public function __construct(UserProviderInterface $user_provider)
    {
        $this->user_provider = $user_provider;
    }

    /**
     * {@inheritdoc}
     *
     * @param ActionInterface $action The action to spread.
     *
     * @return bool
     */
    public function supports(ActionInterface $action)
    {
        // Only supports new posts.
        $object = $action->getComponent('directComplement')->getData();
        if (!$object instanceof Post || 'reply' != $action->getVerb()) {
            return false;
        }

        return true;
    }

    /**
     * {@inheritdoc}
     *
     * @param ActionInterface $action     The action to spread.
     * @param EntryCollection $collection The current spreads.
     *
     * @return void
     */
    public function process(ActionInterface $action, EntryCollection $collection): void
    {
        $post = $action->getComponent('directComplement')->getData();
        $parent = $post->getParent();

        // Spread to authors of posts in the thread.
        $posts = array_merge([$parent], $parent->getChildren()->toArray());
        $done = [];
        foreach ($posts as $check) {
            // Load the author, spread if they have not been spread to yet.
            $author = $this->user_provider->loadUserByUsername($check->getAuthor());
            if (!$author instanceof UserInterface
                || isset($done[$author->getUsername()])) {
                continue;
            }

            $done[$author->getUsername()] = true;
            $collection->add(new EntryUnaware(get_class($author), $author->getId()));
        }
    }
}


<?php

namespace RocknRoot\StrayFw\Database\Postgres;

use RocknRoot\StrayFw\Database\Helper;
use RocknRoot\StrayFw\Exception\InvalidSchemaDefinition;

/**
 * Column helper functions.
 *
 * @abstract
 *
 * @author Nekith <nekith@errant-works.com>
 */
abstract class Column
{
    /**
     * Generate a column SQL fieldDefinition.
     *
     * @throws InvalidSchemaDefinition if default value aren't well typed
     * @throws InvalidSchemaDefinition if a field has an unknown type
     * @param  array                   $schema          schema definition
     * @param  string                  $mapping         mapping name
     * @param  string                  $fieldName       field real name
     * @param  array                   $fieldDefinition field fieldDefinition
     */
    public static function generateDefinition(array $schema, string $mapping, string $fieldName, array $fieldDefinition)
    {
        $sql = $fieldName . ' ';
        switch ($fieldDefinition['type']) {
        case 'bool':
            $sql .= 'BOOL';
            if (isset($fieldDefinition['default']) === true) {
                if (is_bool($fieldDefinition['default']) === false) {
                    throw new InvalidSchemaDefinition('default value for "' . $fieldName . '" isn\'t a boolean');
                }
                $sql .= ' DEFAULT ' . ($fieldDefinition['default'] === true ? 'TRUE' : 'FALSE');
            }
            break;

        case 'char':
            $sql .= 'CHAR(' . (isset($fieldDefinition['size']) === true ? $fieldDefinition['size'] : 45) . ')';
            if (isset($fieldDefinition['default']) === true) {
                $sql .= ' DEFAULT \'' . $fieldDefinition['default'] . '\'';
            }
            break;

        case 'string':
            $sql .= 'VARCHAR(' . (isset($fieldDefinition['size']) === true ? $fieldDefinition['size'] : 45) . ')';
            if (isset($fieldDefinition['default']) === true) {
                $sql .= ' DEFAULT \'' . $fieldDefinition['default'] . '\'';
            }
            break;

        case 'serial':
            $sql .= 'SERIAL';
            break;

        case 'bigserial':
            $sql .= 'BIGSERIAL';
            break;

        case 'int':
            $sql .= 'INT';
            if (isset($fieldDefinition['default']) === true) {
                $sql .= ' DEFAULT \'' . $fieldDefinition['default'] . '\'';
            }
            break;

        case 'smallint':
            $sql .= 'SMALLINT';
            if (isset($fieldDefinition['default']) === true) {
                $sql .= ' DEFAULT \'' . $fieldDefinition['default'] . '\'';
            }
            break;

        case 'float':
            $sql .= 'FLOAT';
            if (isset($fieldDefinition['default']) === true) {
                $sql .= ' DEFAULT \'' . $fieldDefinition['default'] . '\'';
            }
            break;

        case 'numeric':
        case 'decimal':
            $sql .= 'NUMERIC';
            if (isset($fieldDefinition['precision']) === true) {
                $sql .= '(' . $fieldDefinition['precision'];
                if (isset($fieldDefinition['scale']) === true) {
                    $sql .= ', ' . $fieldDefinition['scale'];
                }
                $sql .= ')';
            }
            break;

        case 'timestamp':
            $sql .= 'TIMESTAMP';
            if (isset($fieldDefinition['default']) === true) {
                if ($fieldDefinition['default'] == 'now') {
                    $sql .= ' DEFAULT CURRENT_TIMESTAMP';
                } else {
                    $sql .= ' DEFAULT \'' . $fieldDefinition['default'] . '\'';
                }
            }
            break;

        case 'text':
            $sql .= 'TEXT';
            break;

        case 'json':
            $sql .= 'JSON';
            break;

        case 'blob':
            $sql .= 'BLOB';
            break;

        case 'bit':
            $sql .= 'BIT';
            if (isset($fieldDefinition['size']) === true) {
                $sql .= '(' . $fieldDefinition['size'] . ')';
            }
            break;

        case 'bitstring':
            $sql .= 'BIT VARYING';
            if (isset($fieldDefinition['size']) === true) {
                $sql .= '(' . $fieldDefinition['size'] . ')';
            }
            break;

        default:
            $type = $fieldDefinition['type'];
            if (isset($schema[$type]) === true) {
                if ($schema[$type]['type'] == 'enum') {
                    $enumRealName = null;
                    if (isset($schema[$type]['name']) === true) {
                        $enumRealName = $schema[$type]['name'];
                    } else {
                        $enumRealName = Helper::codifyName($mapping) . '_' . Helper::codifyName($type);
                    }
                    $sql .= $enumRealName;
                    break;
                }
            }
            throw new InvalidSchemaDefinition('field "' . $fieldName . '" has an unknown type');
            break;
        }
        if (isset($fieldDefinition['notnull']) === false || $fieldDefinition['notnull'] === true) {
            $sql .= ' NOT NULL';
        }

        return $sql;
    }
}


<?php

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2016 Spomky-Labs
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

namespace SpomkyLabs\JoseBundle\DependencyInjection\Source\JWKSetSource;

use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

final class Keys extends AbstractJWKSetSource
{
    /**
     * {@inheritdoc}
     */
    public function createDefinition(ContainerBuilder $container, array $config)
    {
        $definition = new Definition('Jose\Object\JWKSet');
        foreach ($config['id'] as $key_id) {
            $ref = new Reference($key_id);
            $definition->addMethodCall('addKey', [$ref]);
        }

        return $definition;
    }

    /**
     * {@inheritdoc}
     */
    public function getKeySet()
    {
        return 'keys';
    }

    /**
     * {@inheritdoc}
     */
    public function addConfiguration(NodeDefinition $node)
    {
        parent::addConfiguration($node);
        $node
            ->children()
                ->arrayNode('id')
                    ->prototype('scalar')
                    ->end()
                    ->isRequired()
                ->end()
            ->end();
    }
}