<commit_before><?php
/*
 * Fusio
 * A web-application to create dynamically RESTful APIs
 *
 * Copyright (C) 2015-2016 <NAME> <<EMAIL>>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace Fusio\Impl\Service;

use Fusio\Impl\Table\App\Scope as TableAppScope;
use Fusio\Impl\Table\Scope as TableScope;
use Fusio\Impl\Table\Scope\Route as TableScopeRoute;
use Fusio\Impl\Table\User\Scope as TableUserScope;
use PSX\Http\Exception as StatusCode;
use PSX\Model\Common\ResultSet;
use PSX\Sql\Sql;
use PSX\Sql\Condition;

/**
 * Scope
 *
 * @author  <NAME> <<EMAIL>>
 * @license http://www.gnu.org/licenses/agpl-3.0
 * @link    http://fusio-project.org
 */
class Scope
{
    protected $scopeTable;
    protected $scopeRouteTable;
    protected $appScopeTable;
    protected $userScopeTable;

    public function __construct(TableScope $scopeTable, TableScopeRoute $scopeRouteTable, TableAppScope $appScopeTable, TableUserScope $userScopeTable)
    {
        $this->scopeTable      = $scopeTable;
        $this->scopeRouteTable = $scopeRouteTable;
        $this->appScopeTable   = $appScopeTable;
        $this->userScopeTable  = $userScopeTable;
    }

    public function getAll($startIndex = 0, $search = null)
    {
        $condition = !empty($search) ? new Condition(['name', 'LIKE', '%' . $search . '%']) : null;

        return new ResultSet(
            $this->scopeTable->getCount($condition),
            $startIndex,
            16,
            $this->scopeTable->getAll(
                $startIndex, 
                16, 
                'id', 
                Sql::SORT_DESC, 
                $condition
            )
        );
    }

    public function getByUser($userId, $startIndex = 0)
    {
        return new ResultSet(
            null,
            null,
            null,
            $this->userScopeTable->getByUser($userId)
        );
    }

    public function get($scopeId)
    {
        $scope = $this->scopeTable->get($scopeId);

        if (!empty($scope)) {
            $scope['routes'] = $this->scopeRouteTable->getByScopeId($scope['id']);

            return $scope;
        } else {
            throw new StatusCode\NotFoundException('Could not find scope');
        }
    }

    public function create($name, $description, array $routes = null)
    {
        // check whether scope exists
        $condition  = new Condition();
        $condition->equals('name', $name);

        $scope = $this->scopeTable->getOneBy($condition);

        if (!empty($scope)) {
            throw new StatusCode\BadRequestException('Scope already exists');
        }

        try {
            $this->scopeTable->beginTransaction();

            // create scope
            $this->scopeTable->create(array(
                'name'        => $name,
                'description' => $description,
            ));

            // insert routes
            $scopeId = $this->scopeTable->getLastInsertId();

            $this->insertRoutes($scopeId, $routes);

            $this->scopeTable->commit();
        } catch (\Exception $e) {
            $this->scopeTable->rollBack();

            throw $e;
        }
    }

    public function update($scopeId, $name, $description, array $routes = null)
    {
        $scope = $this->scopeTable->get($scopeId);

        if (!empty($scope)) {
            try {
                $this->scopeTable->beginTransaction();

                $this->scopeTable->update(array(
                    'id'          => $scope['id'],
                    'name'        => $name,
                    'description' => $description,
                ));

                $this->scopeRouteTable->deleteAllFromScope($scope['id']);

                $this->insertRoutes($scope['id'], $routes);

                $this->scopeTable->commit();
            } catch (\Exception $e) {
                $this->scopeTable->rollBack();

                throw $e;
            }

        } else {
            throw new StatusCode\NotFoundException('Could not find scope');
        }
    }

    public function delete($scopeId)
    {
        $scope = $this->scopeTable->get($scopeId);

        if (!empty($scope)) {
            // check whether the scope is used by an app or user
            $appScopes = $this->appScopeTable->getCount(new Condition(['scopeId', '=', $scope['id']]));
            if ($appScopes > 0) {
                throw new StatusCode\ConflictException('Scope is assigned to an app. Remove the scope from the app in order to delete the scope');
            }

            $userScopes = $this->userScopeTable->getCount(new Condition(['scopeId', '=', $scope['id']]));
            if ($userScopes > 0) {
                throw new StatusCode\ConflictException('Scope is assgined to an user. Remove the scope from the user in order to delete the scope');
            }<commit_msg>block update and deletion of system scopes<commit_after><?php
/*
 * Fusio
 * A web-application to create dynamically RESTful APIs
 *
 * Copyright (C) 2015-2016 <NAME> <<EMAIL>>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace Fusio\Impl\Service;

use Fusio\Impl\Table\App\Scope as TableAppScope;
use Fusio\Impl\Table\Scope as TableScope;
use Fusio\Impl\Table\Scope\Route as TableScopeRoute;
use Fusio\Impl\Table\User\Scope as TableUserScope;
use PSX\Http\Exception as StatusCode;
use PSX\Model\Common\ResultSet;
use PSX\Sql\Sql;
use PSX\Sql\Condition;

/**
 * Scope
 *
 * @author  <NAME> <<EMAIL>>
 * @license http://www.gnu.org/licenses/agpl-3.0
 * @link    http://fusio-project.org
 */
class Scope
{
    protected $scopeTable;
    protected $scopeRouteTable;
    protected $appScopeTable;
    protected $userScopeTable;

    public function __construct(TableScope $scopeTable, TableScopeRoute $scopeRouteTable, TableAppScope $appScopeTable, TableUserScope $userScopeTable)
    {
        $this->scopeTable      = $scopeTable;
        $this->scopeRouteTable = $scopeRouteTable;
        $this->appScopeTable   = $appScopeTable;
        $this->userScopeTable  = $userScopeTable;
    }

    public function getAll($startIndex = 0, $search = null)
    {
        $condition = !empty($search) ? new Condition(['name', 'LIKE', '%' . $search . '%']) : null;

        return new ResultSet(
            $this->scopeTable->getCount($condition),
            $startIndex,
            16,
            $this->scopeTable->getAll(
                $startIndex, 
                16, 
                'id', 
                Sql::SORT_DESC, 
                $condition
            )
        );
    }

    public function getByUser($userId, $startIndex = 0)
    {
        return new ResultSet(
            null,
            null,
            null,
            $this->userScopeTable->getByUser($userId)
        );
    }

    public function get($scopeId)
    {
        $scope = $this->scopeTable->get($scopeId);

        if (!empty($scope)) {
            $scope['routes'] = $this->scopeRouteTable->getByScopeId($scope['id']);

            return $scope;
        } else {
            throw new StatusCode\NotFoundException('Could not find scope');
        }
    }

    public function create($name, $description, array $routes = null)
    {
        // check whether scope exists
        $condition  = new Condition();
        $condition->equals('name', $name);

        $scope = $this->scopeTable->getOneBy($condition);

        if (!empty($scope)) {
            throw new StatusCode\BadRequestException('Scope already exists');
        }

        try {
            $this->scopeTable->beginTransaction();

            // create scope
            $this->scopeTable->create(array(
                'name'        => $name,
                'description' => $description,
            ));

            // insert routes
            $scopeId = $this->scopeTable->getLastInsertId();

            $this->insertRoutes($scopeId, $routes);

            $this->scopeTable->commit();
        } catch (\Exception $e) {
            $this->scopeTable->rollBack();

            throw $e;
        }
    }

    public function update($scopeId, $name, $description, array $routes = null)
    {
        $scope = $this->scopeTable->get($scopeId);

        if (!empty($scope)) {
            // check whether this is a system scope
            if (in_array($scope['id'], [1, 2, 3])) {
                throw new StatusCode\BadRequestException('It is not possible to change this scope');
            }

            try {
                $this->scopeTable->beginTransaction();

                $this->scopeTable->update(array(
                    'id'          => $scope['id'],
                    'name'        => $name,
                    'description' => $description,
                ));

                $this->scopeRouteTable->deleteAllFromScope($scope['id']);

                $this->insertRoutes($scope['id'], $routes);

                $this->scopeTable->commit();
            } catch (\Exception $e) {
                $this->scopeTable->rollBack();

                throw $e;
            }

        } else {
            throw new StatusCode\NotFoundException('Could not find scope');
        }
    }

    public function delete($scopeId)
    {
        $scope = $this->scopeTable->get($scopeId);

        if (!empty($scope)) {
            // check whether the scope is used by an app or user
            $appScopes = $this->appScopeTable->getCount(new Condition(['scopeId', '=', $scope['id']]));
            if ($appScopes > 0) {
                throw new StatusCode\ConflictException('Scope is assigned to an app. Remove the scope from the app in order to delete the scope');
            }

            $userScopes = $this->userScopeTable->getCount(new Condition(['scopeId', '=', $scope['id']]));
            if ($userScopes > 0) {
                throw new StatusCode\ConflictException('Scope is assgined to an user. Remove the scope from the user in order to delete the scope');
            }

            // check whether this is a system scope
            if (in_array($scope['id'], [1, 2, 3])) {
                throw new StatusCode\BadRequestException('It is not possible to change this scope');
            }
{'fraction_non_alphanumeric': 0.12395013703474494, 'fraction_numerical': 0.0038900185659977013, 'mean_word_length': 2.046593051440883, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 125, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4249412', 'n_tokens_mistral': 3139, 'n_tokens_neox': 3010, 'n_words': 828}