<commit_before><?php

/*
 *	Copyright 2015 RhubarbPHP
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

namespace Rhubarb\Stem\Schema;

use Rhubarb\Crown\Context;
use Rhubarb\Crown\Exceptions\ImplementationException;
use Rhubarb\Stem\Exceptions\RelationshipDefinitionException;
use Rhubarb\Stem\Exceptions\SchemaNotFoundException;
use Rhubarb\Stem\Exceptions\SchemaRegistrationException;
use Rhubarb\Stem\Models\Model;
use Rhubarb\Stem\Schema\Relationships\ManyToMany;
use Rhubarb\Stem\Schema\Relationships\OneToMany;
use Rhubarb\Stem\Schema\Relationships\OneToOne;
use Rhubarb\Stem\Schema\Relationships\Relationship;

/**
 * Encapsulates an entire solution schema including it's model objects and the relationships between them.
 *
 * Note that the design of this class is not to store model objects or their schema objects, but rather only the
 * names of the classes involved. This is to ensure that in a big project like Greenbox with 200+ model classes there
 * is not a massive performance penalty for each request.
 */
abstract class SolutionSchema
{
    /**
     * An array of the registered schema classes
     *
     * @var array
     */
    private static $schemaClasses = [];

    /**
     * An array of the initialised schema objects
     *
     * @var array
     */
    private static $schemas = [];

    /**
     * A mapping of model names to model classes
     *
     * @var array
     */
    protected $models = [];

    /**
     * A mapping of model classes to model names
     *
     * @var array
     */
    private $modelClassNames = [];

    /**
     * A collection of relationships defined by this schema
     *
     * @var array
     */
    protected $relationships = [];

    /**
     * A cache array of relationships
     *
     * @var array
     */
    private static $relationshipCache = [];

    /**
     * The version number of the schema.
     *
     * @var int
     */
    protected $version = 0;

    public function __construct($version = 0)
    {
        $this->version = $version;
    }

    /**
     * Registers a schema class to provide the schema for a given schema name.
     *
     * Not that the class should just be a class name, not an instance of the class. This ensures that schema objects
     * (which can be quite large) are only instantiated when needed.
     *
     * @param $schemaName
     * @param $schemaClass
     */
    public static function registerSchema($schemaName, $schemaClass)
    {
        self::$schemaClasses[$schemaName] = $schemaClass;

        // Invalidate the caches
        self::$modelClassesCache = null;
        self::$modelNamesCache = null;
        self::$relationshipCache = null;
    }

    /**
     * Un-registers all solution schemas.
     *
     * Only really used in unit testing.
     */
    public static function clearSchemas()
    {
        self::$schemaClasses = [];
        self::$schemas = [];
    }

    /**
     * The correct place for implementers to define relationships.
     */
    protected function defineRelationships()
    {

    }

    /**
     * Get's an empty model of the appropriate type for a given model name.
     *
     * @param      $modelName
     * @param null $uniqueIdentifier Optionally a unique identifier to load.
     *
     * @return Model
     */
    public static function getModel($modelName, $uniqueIdentifier = null)
    {
        $class = self::getModelClass($modelName);
        $model = new $class($uniqueIdentifier);

        return $model;
    }

    /**
     * Get's the schema for a particular model by name or class.
     *
     * @param string $modelName The name or class name of the model
     * @return ModelSchema
     */
    public static function getModelSchema($modelName)
    {
        $model = self::getModel($modelName);

        return $model->getSchema();<commit_msg>Added a method to allow retrieval of a list of models in the schema<commit_after><?php

/*
 *	Copyright 2015 RhubarbPHP
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

namespace Rhubarb\Stem\Schema;

use Rhubarb\Crown\Context;
use Rhubarb\Crown\Exceptions\ImplementationException;
use Rhubarb\Stem\Exceptions\RelationshipDefinitionException;
use Rhubarb\Stem\Exceptions\SchemaNotFoundException;
use Rhubarb\Stem\Exceptions\SchemaRegistrationException;
use Rhubarb\Stem\Models\Model;
use Rhubarb\Stem\Schema\Relationships\ManyToMany;
use Rhubarb\Stem\Schema\Relationships\OneToMany;
use Rhubarb\Stem\Schema\Relationships\OneToOne;
use Rhubarb\Stem\Schema\Relationships\Relationship;

/**
 * Encapsulates an entire solution schema including it's model objects and the relationships between them.
 *
 * Note that the design of this class is not to store model objects or their schema objects, but rather only the
 * names of the classes involved. This is to ensure that in a big project like Greenbox with 200+ model classes there
 * is not a massive performance penalty for each request.
 */
abstract class SolutionSchema
{
    /**
     * An array of the registered schema classes
     *
     * @var array
     */
    private static $schemaClasses = [];

    /**
     * An array of the initialised schema objects
     *
     * @var array
     */
    private static $schemas = [];

    /**
     * A mapping of model names to model classes
     *
     * @var array
     */
    protected $models = [];

    /**
     * A mapping of model classes to model names
     *
     * @var array
     */
    private $modelClassNames = [];

    /**
     * A collection of relationships defined by this schema
     *
     * @var array
     */
    protected $relationships = [];

    /**
     * A cache array of relationships
     *
     * @var array
     */
    private static $relationshipCache = [];

    /**
     * The version number of the schema.
     *
     * @var int
     */
    protected $version = 0;

    public function __construct($version = 0)
    {
        $this->version = $version;
    }

    /**
     * Registers a schema class to provide the schema for a given schema name.
     *
     * Not that the class should just be a class name, not an instance of the class. This ensures that schema objects
     * (which can be quite large) are only instantiated when needed.
     *
     * @param $schemaName
     * @param $schemaClass
     */
    public static function registerSchema($schemaName, $schemaClass)
    {
        self::$schemaClasses[$schemaName] = $schemaClass;

        // Invalidate the caches
        self::$modelClassesCache = null;
        self::$modelNamesCache = null;
        self::$relationshipCache = null;
    }

    /**
     * Un-registers all solution schemas.
     *
     * Only really used in unit testing.
     */
    public static function clearSchemas()
    {
        self::$schemaClasses = [];
        self::$schemas = [];
    }

    /**
     * The correct place for implementers to define relationships.
     */
    protected function defineRelationships()
    {

    }

    /**
     * Gets an array of all named models and their class names
     *
     * @return Model[]
     */
    public function getAllModels()
    {
        return $this->models;
    }

    /**
     * Gets an empty model of the appropriate type for a given model name.
     *
     * @param      $modelName
     * @param null $uniqueIdentifier Optionally a unique identifier to load.
     *
     * @return Model
     */
    public static function getModel($modelName, $uniqueIdentifier = null)
    {
        $class = self::getModelClass($modelName);
        $model = new $class($uniqueIdentifier);

        return $model;
    }

    /**
     * Get's the schema for a particular model by name or class.
     *
     * @param string $modelName The name or class name of the model
     * @return ModelSchema
     */
    public static function getModelSchema($modelName)
    {
        $model = self::getModel($modelName);

        return $model->getSchema();
{'fraction_non_alphanumeric': 0.089337822671156, 'fraction_numerical': 0.0029180695847362513, 'mean_word_length': 2.537514886859865, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3602001', 'n_tokens_mistral': 2450, 'n_tokens_neox': 2388, 'n_words': 872}