/admin/controller/extension/modification.php
PHP | 791 lines | 521 code | 207 blank | 63 comment | 118 complexity | c2dc1e6004fdc4727e4b315e453c49ee MD5 | raw file
- <?php
- /**
- * Modifcation XML Documentation can be found here:
- *
- * https://github.com/opencart/opencart/wiki/Modification-System
- */
- class ControllerExtensionModification extends Controller {
- private $error = array();
- public function index() {
- $this->load->language('extension/modification');
- $this->document->setTitle($this->language->get('heading_title'));
- $this->load->model('extension/modification');
- $this->getList();
- }
- public function delete() {
- $this->load->language('extension/modification');
- $this->document->setTitle($this->language->get('heading_title'));
- $this->load->model('extension/modification');
- if (isset($this->request->post['selected']) && $this->validate()) {
- foreach ($this->request->post['selected'] as $modification_id) {
- $this->model_extension_modification->deleteModification($modification_id);
- }
- $this->session->data['success'] = $this->language->get('text_success');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $this->response->redirect($this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url, 'SSL'));
- }
- $this->getList();
- }
- public function refresh() {
- $this->load->language('extension/modification');
- $this->document->setTitle($this->language->get('heading_title'));
- $this->load->model('extension/modification');
- if ($this->validate()) {
- // Just before files are deleted, if config settings say maintenance mode is off then turn it on
- $maintenance = $this->config->get('config_maintenance');
- $this->load->model('setting/setting');
- $this->model_setting_setting->editSettingValue('config', 'config_maintenance', true);
- //Log
- $log = array();
- // Clear all modification files
- $files = array();
- // Make path into an array
- $path = array(DIR_MODIFICATION . '*');
- // While the path array is still populated keep looping through
- while (count($path) != 0) {
- $next = array_shift($path);
- foreach (glob($next) as $file) {
- // If directory add to path array
- if (is_dir($file)) {
- $path[] = $file . '/*';
- }
- // Add the file to the files to be deleted array
- $files[] = $file;
- }
- }
- // Reverse sort the file array
- rsort($files);
- // Clear all modification files
- foreach ($files as $file) {
- if ($file != DIR_MODIFICATION . 'index.html') {
- // If file just delete
- if (is_file($file)) {
- unlink($file);
- // If directory use the remove directory function
- } elseif (is_dir($file)) {
- rmdir($file);
- }
- }
- }
- // Begin
- $xml = array();
- // Load the default modification XML
- $xml[] = file_get_contents(DIR_SYSTEM . 'modification.xml');
- // This is purly for developers so they can run mods directly and have them run without upload sfter each change.
- $files = glob(DIR_SYSTEM . '*.ocmod.xml');
- if ($files) {
- foreach ($files as $file) {
- $xml[] = file_get_contents($file);
- }
- }
- // Get the default modification file
- $results = $this->model_extension_modification->getModifications();
- foreach ($results as $result) {
- if ($result['status']) {
- $xml[] = $result['xml'];
- }
- }
- $modification = array();
- foreach ($xml as $xml) {
- $dom = new DOMDocument('1.0', 'UTF-8');
- $dom->preserveWhiteSpace = false;
- $dom->loadXml($xml);
- // Log
- $log[] = 'MOD: ' . $dom->getElementsByTagName('name')->item(0)->textContent;
- // Wipe the past modification store in the backup array
- $recovery = array();
- // Set the a recovery of the modification code in case we need to use it if an abort attribute is used.
- if (isset($modification)) {
- $recovery = $modification;
- }
- $files = $dom->getElementsByTagName('modification')->item(0)->getElementsByTagName('file');
- foreach ($files as $file) {
- $operations = $file->getElementsByTagName('operation');
- $files = explode('|', $file->getAttribute('path'));
- foreach ($files as $file) {
- $path = '';
- // Get the full path of the files that are going to be used for modification
- if (substr($file, 0, 7) == 'catalog') {
- $path = DIR_CATALOG . str_replace('../', '', substr($file, 8));
- }
- if (substr($file, 0, 5) == 'admin') {
- $path = DIR_APPLICATION . str_replace('../', '', substr($file, 6));
- }
- if (substr($file, 0, 6) == 'system') {
- $path = DIR_SYSTEM . str_replace('../', '', substr($file, 7));
- }
- if ($path) {
- $files = glob($path, GLOB_BRACE);
- if ($files) {
- foreach ($files as $file) {
- // Get the key to be used for the modification cache filename.
- if (substr($file, 0, strlen(DIR_CATALOG)) == DIR_CATALOG) {
- $key = 'catalog/' . substr($file, strlen(DIR_CATALOG));
- }
- if (substr($file, 0, strlen(DIR_APPLICATION)) == DIR_APPLICATION) {
- $key = 'admin/' . substr($file, strlen(DIR_APPLICATION));
- }
- if (substr($file, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) {
- $key = 'system/' . substr($file, strlen(DIR_SYSTEM));
- }
- // If file contents is not already in the modification array we need to load it.
- if (!isset($modification[$key])) {
- $content = file_get_contents($file);
- $modification[$key] = preg_replace('~\r?\n~', "\n", $content);
- $original[$key] = preg_replace('~\r?\n~', "\n", $content);
- // Log
- $log[] = 'FILE: ' . $key;
- }
- foreach ($operations as $operation) {
- $error = $operation->getAttribute('error');
- // Ignoreif
- $ignoreif = $operation->getElementsByTagName('ignoreif')->item(0);
- if ($ignoreif) {
- if ($ignoreif->getAttribute('regex') != 'true') {
- if (strpos($modification[$key], $ignoreif->textContent) !== false) {
- continue;
- }
- } else {
- if (preg_match($ignoreif->textContent, $modification[$key])) {
- continue;
- }
- }
- }
- $status = false;
- // Search and replace
- if ($operation->getElementsByTagName('search')->item(0)->getAttribute('regex') != 'true') {
- // Search
- $search = $operation->getElementsByTagName('search')->item(0)->textContent;
- $trim = $operation->getElementsByTagName('search')->item(0)->getAttribute('trim');
- $index = $operation->getElementsByTagName('search')->item(0)->getAttribute('index');
- // Trim line if no trim attribute is set or is set to true.
- if (!$trim || $trim == 'true') {
- $search = trim($search);
- }
- // Add
- $add = $operation->getElementsByTagName('add')->item(0)->textContent;
- $trim = $operation->getElementsByTagName('add')->item(0)->getAttribute('trim');
- $position = $operation->getElementsByTagName('add')->item(0)->getAttribute('position');
- $offset = $operation->getElementsByTagName('add')->item(0)->getAttribute('offset');
- if ($offset == '') {
- $offset = 0;
- }
- // Trim line if is set to true.
- if ($trim == 'true') {
- $add = trim($add);
- }
- // Log
- $log[] = 'CODE: ' . $search;
- // Check if using indexes
- if ($index !== '') {
- $indexes = explode(',', $index);
- } else {
- $indexes = array();
- }
- // Get all the matches
- $i = 0;
- $lines = explode("\n", $modification[$key]);
- for ($line_id = 0; $line_id < count($lines); $line_id++) {
- $line = $lines[$line_id];
- // Status
- $match = false;
- // Check to see if the line matches the search code.
- if (stripos($line, $search) !== false) {
- // If indexes are not used then just set the found status to true.
- if (!$indexes) {
- $match = true;
- } elseif (in_array($i, $indexes)) {
- $match = true;
- }
- $i++;
- }
- // Now for replacing or adding to the matched elements
- if ($match) {
- switch ($position) {
- default:
- case 'replace':
- $new_lines = explode("\n", $add);
- if ($offset < 0) {
- array_splice($lines, $line_id + $offset, abs($offset) + 1, array(str_replace($search, $add, $line)));
- $line_id -= $offset;
- } else {
- array_splice($lines, $line_id, $offset + 1, array(str_replace($search, $add, $line)));
- }
- break;
- case 'before':
- $new_lines = explode("\n", $add);
- array_splice($lines, $line_id - $offset, 0, $new_lines);
- $line_id += count($new_lines);
- break;
- case 'after':
- $new_lines = explode("\n", $add);
- array_splice($lines, ($line_id + 1) + $offset, 0, $new_lines);
- $line_id += count($new_lines);
- break;
- }
- // Log
- $log[] = 'LINE: ' . $line_id;
- $status = true;
- }
- }
- $modification[$key] = implode("\n", $lines);
- } else {
- $search = trim($operation->getElementsByTagName('search')->item(0)->textContent);
- $limit = $operation->getElementsByTagName('search')->item(0)->getAttribute('limit');
- $replace = trim($operation->getElementsByTagName('add')->item(0)->textContent);
- // Limit
- if (!$limit) {
- $limit = -1;
- }
- // Log
- $match = array();
- preg_match_all($search, $modification[$key], $match, PREG_OFFSET_CAPTURE);
- // Remove part of the the result if a limit is set.
- if ($limit > 0) {
- $match[0] = array_slice($match[0], 0, $limit);
- }
- if ($match[0]) {
- $log[] = 'REGEX: ' . $search;
- for ($i = 0; $i < count($match[0]); $i++) {
- $log[] = 'LINE: ' . (substr_count(substr($modification[$key], 0, $match[0][$i][1]), "\n") + 1);
- }
- $status = true;
- }
- // Make the modification
- $modification[$key] = preg_replace($search, $replace, $modification[$key], $limit);
- }
- if (!$status) {
- // Log
- $log[] = 'NOT FOUND!';
- // Skip current operation
- if ($error == 'skip') {
- break;
- }
- // Abort applying this modification completely.
- if ($error == 'abort') {
- $modification = $recovery;
- // Log
- $log[] = 'ABORTING!';
- break 5;
- }
- }
- }
- }
- }
- }
- }
- }
- // Log
- $log[] = '----------------------------------------------------------------';
- }
- // Log
- $ocmod = new Log('ocmod.log');
- $ocmod->write(implode("\n", $log));
- // Write all modification files
- foreach ($modification as $key => $value) {
- // Only create a file if there are changes
- if ($original[$key] != $value) {
- $path = '';
- $directories = explode('/', dirname($key));
- foreach ($directories as $directory) {
- $path = $path . '/' . $directory;
- if (!is_dir(DIR_MODIFICATION . $path)) {
- @mkdir(DIR_MODIFICATION . $path, 0777);
- }
- }
- $handle = fopen(DIR_MODIFICATION . $key, 'w');
- fwrite($handle, $value);
- fclose($handle);
- }
- }
- // Maintance mode back to original settings
- $this->model_setting_setting->editSettingValue('config', 'config_maintenance', $maintenance);
- $this->session->data['success'] = $this->language->get('text_success');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $this->response->redirect($this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url, 'SSL'));
- }
- $this->getList();
- }
- public function clear() {
- $this->load->language('extension/modification');
- $this->document->setTitle($this->language->get('heading_title'));
- $this->load->model('extension/modification');
- if ($this->validate()) {
- $files = array();
- // Make path into an array
- $path = array(DIR_MODIFICATION . '*');
- // While the path array is still populated keep looping through
- while (count($path) != 0) {
- $next = array_shift($path);
- foreach (glob($next) as $file) {
- // If directory add to path array
- if (is_dir($file)) {
- $path[] = $file . '/*';
- }
- // Add the file to the files to be deleted array
- $files[] = $file;
- }
- }
- // Reverse sort the file array
- rsort($files);
- // Clear all modification files
- foreach ($files as $file) {
- if ($file != DIR_MODIFICATION . 'index.html') {
- // If file just delete
- if (is_file($file)) {
- unlink($file);
- // If directory use the remove directory function
- } elseif (is_dir($file)) {
- rmdir($file);
- }
- }
- }
- $this->session->data['success'] = $this->language->get('text_success');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $this->response->redirect($this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url, 'SSL'));
- }
- $this->getList();
- }
- public function enable() {
- $this->load->language('extension/modification');
- $this->document->setTitle($this->language->get('heading_title'));
- $this->load->model('extension/modification');
- if (isset($this->request->get['modification_id']) && $this->validate()) {
- $this->model_extension_modification->enableModification($this->request->get['modification_id']);
- $this->session->data['success'] = $this->language->get('text_success');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $this->response->redirect($this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url, 'SSL'));
- }
- $this->getList();
- }
- public function disable() {
- $this->load->language('extension/modification');
- $this->document->setTitle($this->language->get('heading_title'));
- $this->load->model('extension/modification');
- if (isset($this->request->get['modification_id']) && $this->validate()) {
- $this->model_extension_modification->disableModification($this->request->get['modification_id']);
- $this->session->data['success'] = $this->language->get('text_success');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $this->response->redirect($this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url, 'SSL'));
- }
- $this->getList();
- }
- public function clearlog() {
- $this->load->language('extension/modification');
- if ($this->validate()) {
- $handle = fopen(DIR_LOGS . 'ocmod.log', 'w+');
- fclose($handle);
- $this->session->data['success'] = $this->language->get('text_success');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $this->response->redirect($this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url, 'SSL'));
- }
- $this->getList();
- }
- protected function getList() {
- if (isset($this->request->get['sort'])) {
- $sort = $this->request->get['sort'];
- } else {
- $sort = 'name';
- }
- if (isset($this->request->get['order'])) {
- $order = $this->request->get['order'];
- } else {
- $order = 'ASC';
- }
- if (isset($this->request->get['page'])) {
- $page = $this->request->get['page'];
- } else {
- $page = 1;
- }
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $data['breadcrumbs'] = array();
- $data['breadcrumbs'][] = array(
- 'text' => $this->language->get('text_home'),
- 'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], 'SSL')
- );
- $data['breadcrumbs'][] = array(
- 'text' => $this->language->get('heading_title'),
- 'href' => $this->url->link('extension/modification', 'token=' . $this->session->data['token'], 'SSL')
- );
- $data['refresh'] = $this->url->link('extension/modification/refresh', 'token=' . $this->session->data['token'] . $url, 'SSL');
- $data['clear'] = $this->url->link('extension/modification/clear', 'token=' . $this->session->data['token'] . $url, 'SSL');
- $data['delete'] = $this->url->link('extension/modification/delete', 'token=' . $this->session->data['token'] . $url, 'SSL');
- $data['modifications'] = array();
- $filter_data = array(
- 'sort' => $sort,
- 'order' => $order,
- 'start' => ($page - 1) * $this->config->get('config_limit_admin'),
- 'limit' => $this->config->get('config_limit_admin')
- );
- $modification_total = $this->model_extension_modification->getTotalModifications();
- $results = $this->model_extension_modification->getModifications($filter_data);
- foreach ($results as $result) {
- $data['modifications'][] = array(
- 'modification_id' => $result['modification_id'],
- 'name' => $result['name'],
- 'author' => $result['author'],
- 'version' => $result['version'],
- 'status' => $result['status'] ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),
- 'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])),
- 'link' => $result['link'],
- 'enable' => $this->url->link('extension/modification/enable', 'token=' . $this->session->data['token'] . '&modification_id=' . $result['modification_id'], 'SSL'),
- 'disable' => $this->url->link('extension/modification/disable', 'token=' . $this->session->data['token'] . '&modification_id=' . $result['modification_id'], 'SSL'),
- 'enabled' => $result['status'],
- );
- }
- $data['heading_title'] = $this->language->get('heading_title');
- $data['text_list'] = $this->language->get('text_list');
- $data['text_no_results'] = $this->language->get('text_no_results');
- $data['text_confirm'] = $this->language->get('text_confirm');
- $data['text_refresh'] = $this->language->get('text_refresh');
- $data['column_name'] = $this->language->get('column_name');
- $data['column_author'] = $this->language->get('column_author');
- $data['column_version'] = $this->language->get('column_version');
- $data['column_status'] = $this->language->get('column_status');
- $data['column_date_added'] = $this->language->get('column_date_added');
- $data['column_action'] = $this->language->get('column_action');
- $data['button_refresh'] = $this->language->get('button_refresh');
- $data['button_clear'] = $this->language->get('button_clear');
- $data['button_delete'] = $this->language->get('button_delete');
- $data['button_link'] = $this->language->get('button_link');
- $data['button_enable'] = $this->language->get('button_enable');
- $data['button_disable'] = $this->language->get('button_disable');
- $data['tab_general'] = $this->language->get('tab_general');
- $data['tab_log'] = $this->language->get('tab_log');
- $data['token'] = $this->session->data['token'];
- if (isset($this->error['warning'])) {
- $data['error_warning'] = $this->error['warning'];
- } else {
- $data['error_warning'] = '';
- }
- if (isset($this->session->data['success'])) {
- $data['success'] = $this->session->data['success'];
- unset($this->session->data['success']);
- } else {
- $data['success'] = '';
- }
- if (isset($this->request->post['selected'])) {
- $data['selected'] = (array)$this->request->post['selected'];
- } else {
- $data['selected'] = array();
- }
- $url = '';
- if ($order == 'ASC') {
- $url .= '&order=DESC';
- } else {
- $url .= '&order=ASC';
- }
- if (isset($this->request->get['page'])) {
- $url .= '&page=' . $this->request->get['page'];
- }
- $data['sort_name'] = $this->url->link('extension/modification', 'token=' . $this->session->data['token'] . '&sort=name' . $url, 'SSL');
- $data['sort_author'] = $this->url->link('extension/modification', 'token=' . $this->session->data['token'] . '&sort=author' . $url, 'SSL');
- $data['sort_version'] = $this->url->link('extension/version', 'token=' . $this->session->data['token'] . '&sort=author' . $url, 'SSL');
- $data['sort_status'] = $this->url->link('extension/modification', 'token=' . $this->session->data['token'] . '&sort=status' . $url, 'SSL');
- $data['sort_date_added'] = $this->url->link('extension/modification', 'token=' . $this->session->data['token'] . '&sort=date_added' . $url, 'SSL');
- $url = '';
- if (isset($this->request->get['sort'])) {
- $url .= '&sort=' . $this->request->get['sort'];
- }
- if (isset($this->request->get['order'])) {
- $url .= '&order=' . $this->request->get['order'];
- }
- $pagination = new Pagination();
- $pagination->total = $modification_total;
- $pagination->page = $page;
- $pagination->limit = $this->config->get('config_limit_admin');
- $pagination->url = $this->url->link('extension/modification', 'token=' . $this->session->data['token'] . $url . '&page={page}', 'SSL');
- $data['pagination'] = $pagination->render();
- $data['results'] = sprintf($this->language->get('text_pagination'), ($modification_total) ? (($page - 1) * $this->config->get('config_limit_admin')) + 1 : 0, ((($page - 1) * $this->config->get('config_limit_admin')) > ($modification_total - $this->config->get('config_limit_admin'))) ? $modification_total : ((($page - 1) * $this->config->get('config_limit_admin')) + $this->config->get('config_limit_admin')), $modification_total, ceil($modification_total / $this->config->get('config_limit_admin')));
- $data['sort'] = $sort;
- $data['order'] = $order;
- // Log
- $file = DIR_LOGS . 'ocmod.log';
- if (file_exists($file)) {
- $data['log'] = htmlentities(file_get_contents($file, FILE_USE_INCLUDE_PATH, null));
- } else {
- $data['log'] = '';
- }
- $data['clear_log'] = $this->url->link('extension/modification/clearlog', 'token=' . $this->session->data['token'], 'SSL');
- $data['header'] = $this->load->controller('common/header');
- $data['column_left'] = $this->load->controller('common/column_left');
- $data['footer'] = $this->load->controller('common/footer');
- $this->response->setOutput($this->load->view('extension/modification.tpl', $data));
- }
- protected function validate() {
- if (!$this->user->hasPermission('modify', 'extension/modification')) {
- $this->error['warning'] = $this->language->get('error_permission');
- }
- return !$this->error;
- }
- }