Completed
Push — master ( 170cc1...c04f2c )
by Iurii
01:05
created

Editor::save()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 1
1
<?php
2
3
/**
4
 * @package Theme editor
5
 * @author Iurii Makukh <[email protected]>
6
 * @copyright Copyright (c) 2015, Iurii Makukh
7
 * @license https://www.gnu.org/licenses/gpl.html GNU/GPLv3
8
 */
9
10
namespace gplcart\modules\editor\models;
11
12
use gplcart\core\Model;
13
use gplcart\core\models\Language as LanguageModel;
14
15
/**
16
 * Manages basic behaviors and data related to Theme Editor module
17
 */
18
class Editor extends Model
19
{
20
21
    /**
22
     * Language model instance
23
     * @var \gplcart\core\models\Language $language
24
     */
25
    protected $language;
26
27
    /**
28
     * @param LanguageModel $language
29
     */
30
    public function __construct(LanguageModel $language)
31
    {
32
        parent::__construct();
33
34
        $this->language = $language;
35
    }
36
37
    /**
38
     * Returns an array of editable files
39
     * @param array $module
40
     * @return array
41
     */
42
    public function getList(array $module)
43
    {
44
        $list = array();
45
        foreach ($this->getScanFolders() as $folder) {
46
            $files = gplcart_file_scan_recursive("{$module['directory']}/$folder");
47
            sort($files);
48
            $list[$folder] = $files;
49
        }
50
51
        $this->hook->attach('module.editor.list', $list);
52
        return $list;
53
    }
54
55
    /**
56
     * Returns an array of folder names to scan
57
     * @return array
58
     */
59
    protected function getScanFolders()
60
    {
61
        return array('templates', 'css', 'js');
62
    }
63
64
    /**
65
     * Saves an edited file
66
     * @param array $data
67
     * @return boolean
68
     */
69
    public function save($data)
70
    {
71
        $result = null;
72
        $this->hook->attach('module.editor.save.before', $data, $result);
73
74
        if (isset($result)) {
75
            return $result;
76
        }
77
78
        if ($this->backup($data) !== true) {
79
            return false;
80
        }
81
82
        $result = $this->write($data['content'], $data['path']);
83
        $this->hook->attach('module.editor.save.after', $data, $result);
84
        return $result;
85
    }
86
87
    /**
88
     * Backup a module
89
     * @param array $data
90
     * @return bool
91
     */
92
    protected function backup(array $data)
93
    {
94
        /* @var $backup \gplcart\modules\backup\Backup */
95
        $backup = $this->config->getModuleInstance('backup');
96
97
        $has_backup = true;
98
        if (!$backup->exists($data['module']['id'])) {
99
            $has_backup = $backup->backup('module', $data['module']);
100
        }
101
102
        return $has_backup;
103
    }
104
105
    /**
106
     * Writes a content to a file
107
     * @param string $content
108
     * @param string $file
109
     * @return boolean
110
     */
111
    protected function write($content, $file)
112
    {
113
        if (file_exists($file)) { // Do not create a new file
114
            return file_put_contents($file, $content) !== false;
115
        }
116
117
        return false;
118
    }
119
120
    /**
121
     * Tries to validate syntax of a PHP file
122
     * @param string $file
123
     * @return mixed
124
     */
125
    public function validatePhpFile($file)
126
    {
127
        if (!$this->canValidatePhpCode()) {
128
            return null;
129
        }
130
131
        $output = shell_exec('php -l ' . escapeshellarg($file));
132
133
        $count = 0;
134
        $error = preg_replace('/Errors parsing.*$/', '', $output, -1, $count);
135
        return $count > 0 ? trim("$error") : true;
136
    }
137
138
    /**
139
     * Whether it's possible to validate a PHP code
140
     * @return bool
141
     */
142
    public function canValidatePhpCode()
143
    {
144
        return function_exists('shell_exec') && !in_array('shell_exec', explode(',', ini_get('disable_functions')));
145
    }
146
147
    /**
148
     * Tries to validate a PHP code
149
     * @param string $code
150
     * @return mixed
151
     */
152
    public function validatePhpCode($code)
153
    {
154
        $temp = tmpfile();
155
        fwrite($temp, $code);
156
        $meta_data = stream_get_meta_data($temp);
157
158
        $result = $this->validatePhpFile($meta_data['uri']);
159
        fclose($temp);
160
        return $result;
161
    }
162
163
}
164