Completed
Push — master ( 241dbe...908ab6 )
by Nikita
03:49
created

CMS::afterCompress()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 12
rs 9.4286
cc 3
eloc 5
nc 3
nop 2
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 20 and the first side effect is on line 5.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
namespace samsoncms\api;
3
4
// Backward compatibility
5
require('generated/Material.php');
6
require('generated/Field.php');
7
require('generated/MaterialField.php');
8
require('generated/Structure.php');
9
require('generated/StructureField.php');
10
11
use samson\activerecord\structurematerial;
12
use samson\activerecord\TableRelation;
13
use samson\core\CompressableService;
14
use samson\activerecord\dbMySQLConnector;
15
16
/**
17
 * SamsonCMS API
18
 * @package samsoncms\api
19
 */
20
class CMS extends CompressableService
21
{
22
    /** Database entity name for relations between material and navigation */
23
    const MATERIAL_NAVIGATION_RELATION_ENTITY = '\samson\activerecord\structurematerial';
24
    /** Database entity name for relations between material and images */
25
    const MATERIAL_IMAGES_RELATION_ENTITY = '\samson\activerecord\gallery';
26
    /** Database entity name for relations between additional fields and navigation */
27
    const FIELD_NAVIGATION_RELATION_ENTITY = '\samson\activerecord\structurefield';
28
    /** Database entity name for relations between material and additional fields values */
29
    const MATERIAL_FIELD_RELATION_ENTITY = MaterialField::ENTITY;
30
31
    /** Identifier */
32
    protected $id = 'cmsapi2';
33
34
    /** @var \samsonframework\orm\DatabaseInterface */
35
    protected $database;
36
37
    /** @var string Database table names prefix */
38
    public $tablePrefix = '';
39
40
    /**
41
     * CMS constructor.
42
     * @param null|string $path
43
     * @param null|string $vid
44
     * @param mixed|null $resources
45
     */
46
    public function __construct($path, $vid, $resources)
47
    {
48
        // TODO: This should changed to normal DI
49
        $this->database = db();
50
51
        parent::__construct($path, $vid, $resources);
52
    }
53
54
55
    public function beforeCompress(& $obj = null, array & $code = null)
56
    {
57
58
    }
59
60
    public function afterCompress(& $obj = null, array & $code = null)
61
    {
62
        // Iterate through generated php code
63
        $files = array();
64
        foreach (\samson\core\File::dir($this->cache_path, 'php', '', $files, 1) as $file) {
65
            // No namespace for global function file
66
            $ns = strpos($file, 'func') === false ? __NAMESPACE__ : '';
67
68
            // Compress generated php code
69
            $obj->compress_php($file, $this, $code, $ns);
70
        }
71
    }
72
73
    //[PHPCOMPRESSOR(remove,start)]
74
    /**
75
     * Read SQL file with variables placeholders pasting
76
     * @param string $filePath SQL file for reading
77
     * @param string $prefix Prefix for addition
78
     * @return string SQL command text
79
     */
80
    public function readSQL($filePath, $prefix = '')
81
    {
82
        $sql = '';
83
84
        // Build path to SQL folder
85
        if (file_exists($filePath)) {
86
            // Replace prefix
87
            $sql = str_replace('@prefix', $prefix, file_get_contents($filePath));
88
        }
89
90
        return $sql;
91
    }
92
93
    /**
94
     * @see ModuleConnector::prepare()
95
     */
96
    public function prepare()
97
    {
98
        // Perform this migration and execute only once
99
        if ($this->migrator() != 40) {
100
            // Perform SQL table creation
101
            $path = __DIR__ . '/../sql/';
102
            foreach (array_slice(scandir($path), 2) as $file) {
103
                $this->database->execute($this->readSQL($path . $file, $this->tablePrefix));
104
            }
105
            $this->migrator(40);
106
        }
107
108
        // Initiate migration mechanism
109
        $this->database->migration(get_class($this), array($this, 'migrator'));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface samsonframework\orm\DatabaseInterface as the method migration() does only exist in the following implementations of said interface: samson\activerecord\dbMySQL.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
110
111
                // Define permanent table relations
112
        new TableRelation('material', 'user', 'UserID', 0, 'user_id');
113
        new TableRelation('material', 'gallery', 'MaterialID', TableRelation::T_ONE_TO_MANY);
114
        new TableRelation('material', 'materialfield', 'MaterialID', TableRelation::T_ONE_TO_MANY);
115
        new TableRelation('material', 'field', 'materialfield.FieldID', TableRelation::T_ONE_TO_MANY);
116
        new TableRelation('material', 'structurematerial', 'MaterialID', TableRelation::T_ONE_TO_MANY);
117
        new TableRelation('material', 'structure', 'structurematerial.StructureID', TableRelation::T_ONE_TO_MANY);
118
        new TableRelation('materialfield', 'field', 'FieldID');
119
        new TableRelation('materialfield', 'material', 'MaterialID');
120
        new TableRelation('structurematerial', 'structure', 'StructureID');
121
        new TableRelation('structurematerial', 'materialfield', 'MaterialID', TableRelation::T_ONE_TO_MANY);
122
        new TableRelation('structurematerial', 'material', 'MaterialID', TableRelation::T_ONE_TO_MANY);
123
        new TableRelation('structure', 'material', 'structurematerial.MaterialID', TableRelation::T_ONE_TO_MANY, null, 'manymaterials');
124
        new TableRelation('structure', 'gallery', 'structurematerial.MaterialID', TableRelation::T_ONE_TO_MANY, null, 'manymaterials');
125
        /*new TableRelation( 'structure', 'material', 'MaterialID' );*/
126
        new TableRelation('structure', 'user', 'UserID', 0, 'user_id');
127
        new TableRelation('structure', 'materialfield', 'material.MaterialID', TableRelation::T_ONE_TO_MANY, 'MaterialID', '_mf');
128
        new TableRelation('structure', 'structurematerial', 'StructureID', TableRelation::T_ONE_TO_MANY);
129
        new TableRelation('related_materials', 'material', 'first_material', TableRelation::T_ONE_TO_MANY, 'MaterialID');
130
        new TableRelation('related_materials', 'materialfield', 'first_material', TableRelation::T_ONE_TO_MANY, 'MaterialID');
131
        new TableRelation('field', 'structurefield', 'FieldID');
132
        new TableRelation('field', 'structure', 'structurefield.StructureID');
133
        new TableRelation('structurefield', 'field', 'FieldID');
134
        new TableRelation('structurefield', 'materialfield', 'FieldID');
135
        new TableRelation('structurefield', 'material', 'materialfield.MaterialID');
136
        new TableRelation('structure', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'parent_id', 'children_relations');
137
        new TableRelation('structure', 'structure', 'children_relations.child_id', TableRelation::T_ONE_TO_MANY, 'StructureID', 'children');
138
        new TableRelation('structure', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'child_id', 'parents_relations');
139
        new TableRelation('structure', 'structure', 'parents_relations.parent_id', TableRelation::T_ONE_TO_MANY, 'StructureID', 'parents');
140
        new TableRelation('structurematerial', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'parent_id');
141
        new TableRelation('groupright', 'right', 'RightID', TableRelation::T_ONE_TO_MANY);
142
143
        m('activerecord')->relations();
144
145
        // Generate entities classes file
146
        $generator = new Generator($this->database);
147
        $file = md5($generator->entityHash()).'.php';
148
        if ($this->cache_refresh($file)) {
149
150
        }
151
        file_put_contents($file, '<?php '.$generator->createEntityClasses());
152
153
        // Include entities file
154
        require($file);
155
156
        return parent::prepare();
157
    }
158
159
    /**
160
     * Handler for CMSAPI database version manipulating
161
     * @param string $toVersion Version to switch to
162
     * @return string Current database version
163
     */
164
    public function migrator($toVersion = null)
165
    {
166
        // If something passed - change database version to it
167
        if (func_num_args()) {
168
            // Save current version to special db table
169
            $this->database->execute(
170
                "ALTER TABLE  `" . dbMySQLConnector::$prefix . "cms_version`
171
                CHANGE  `version`  `version` VARCHAR( 15 ) CHARACTER SET utf8
172
                COLLATE utf8_general_ci NOT NULL DEFAULT  '" . $toVersion . "';"
173
            );
174
            die('Database successfully migrated to [' . $toVersion . ']');
175
        } else { // Return current database version
176
            $version_row = $this->database->fetch('SHOW COLUMNS FROM `' . dbMySQLConnector::$prefix . 'cms_version`');
177
            if (isset($version_row[0]['Default'])) {
178
                return $version_row[0]['Default'];
179
            } else {
180
                return 0;
181
            }
182
        }
183
    }
184
    //[PHPCOMPRESSOR(remove,end)]
185
}
186