aboutsummaryrefslogtreecommitdiffstats
path: root/public/admin/controller/marketplace/modification.php
diff options
context:
space:
mode:
Diffstat (limited to 'public/admin/controller/marketplace/modification.php')
-rw-r--r--public/admin/controller/marketplace/modification.php777
1 files changed, 777 insertions, 0 deletions
diff --git a/public/admin/controller/marketplace/modification.php b/public/admin/controller/marketplace/modification.php
new file mode 100644
index 0000000..f094fc1
--- /dev/null
+++ b/public/admin/controller/marketplace/modification.php
@@ -0,0 +1,777 @@
+<?php
+/**
+ * Modifcation XML Documentation can be found here:
+ *
+ * https://github.com/opencart/opencart/wiki/Modification-System
+ */
+class ControllerMarketplaceModification extends Controller {
+ private $error = array();
+
+ public function index() {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/modification');
+
+ $this->getList();
+ }
+
+ public function delete() {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/modification');
+
+ if (isset($this->request->post['selected']) && $this->validate()) {
+ foreach ($this->request->post['selected'] as $modification_id) {
+ $this->model_setting_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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url, true));
+ }
+
+ $this->getList();
+ }
+
+ public function refresh($data = array()) {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/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 after 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_setting_modification->getModifications();
+
+ foreach ($results as $result) {
+ if ($result['status']) {
+ $xml[] = $result['xml'];
+ }
+ }
+
+ $modification = array();
+
+ foreach ($xml as $xml) {
+ if (empty($xml)){
+ continue;
+ }
+
+ $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 . substr($file, 8);
+ }
+
+ if ((substr($file, 0, 5) == 'admin')) {
+ $path = DIR_APPLICATION . substr($file, 6);
+ }
+
+ if ((substr($file, 0, 6) == 'system')) {
+ $path = DIR_SYSTEM . 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[] = PHP_EOL . '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) {
+ // Abort applying this modification completely.
+ if ($error == 'abort') {
+ $modification = $recovery;
+ // Log
+ $log[] = 'NOT FOUND - ABORTING!';
+ break 5;
+ }
+ // Skip current operation or break
+ elseif ($error == 'skip') {
+ // Log
+ $log[] = 'NOT FOUND - OPERATION SKIPPED!';
+ continue;
+ }
+ // Break current operations
+ else {
+ // Log
+ $log[] = 'NOT FOUND - OPERATIONS ABORTED!';
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 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);
+
+ // Do not return success message if refresh() was called with $data
+ $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(!empty($data['redirect']) ? $data['redirect'] : 'marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url, true));
+ }
+
+ $this->getList();
+ }
+
+ public function clear() {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url, true));
+ }
+
+ $this->getList();
+ }
+
+ public function enable() {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/modification');
+
+ if (isset($this->request->get['modification_id']) && $this->validate()) {
+ $this->model_setting_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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url, true));
+ }
+
+ $this->getList();
+ }
+
+ public function disable() {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/modification');
+
+ if (isset($this->request->get['modification_id']) && $this->validate()) {
+ $this->model_setting_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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url, true));
+ }
+
+ $this->getList();
+ }
+
+ public function clearlog() {
+ $this->load->language('marketplace/modification');
+
+ $this->document->setTitle($this->language->get('heading_title'));
+
+ $this->load->model('setting/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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url, true));
+ }
+
+ $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', 'user_token=' . $this->session->data['user_token'], true)
+ );
+
+ $data['breadcrumbs'][] = array(
+ 'text' => $this->language->get('heading_title'),
+ 'href' => $this->url->link('marketplace/modification', 'user_token=' . $this->session->data['user_token'], true)
+ );
+
+ $data['refresh'] = $this->url->link('marketplace/modification/refresh', 'user_token=' . $this->session->data['user_token'] . $url, true);
+ $data['clear'] = $this->url->link('marketplace/modification/clear', 'user_token=' . $this->session->data['user_token'] . $url, true);
+ $data['delete'] = $this->url->link('marketplace/modification/delete', 'user_token=' . $this->session->data['user_token'] . $url, true);
+
+ $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_setting_modification->getTotalModifications();
+
+ $results = $this->model_setting_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('marketplace/modification/enable', 'user_token=' . $this->session->data['user_token'] . '&modification_id=' . $result['modification_id'], true),
+ 'disable' => $this->url->link('marketplace/modification/disable', 'user_token=' . $this->session->data['user_token'] . '&modification_id=' . $result['modification_id'], true),
+ 'enabled' => $result['status']
+ );
+ }
+
+ $data['user_token'] = $this->session->data['user_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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . '&sort=name' . $url, true);
+ $data['sort_author'] = $this->url->link('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . '&sort=author' . $url, true);
+ $data['sort_version'] = $this->url->link('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . '&sort=version' . $url, true);
+ $data['sort_status'] = $this->url->link('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . '&sort=status' . $url, true);
+ $data['sort_date_added'] = $this->url->link('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . '&sort=date_added' . $url, true);
+
+ $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('marketplace/modification', 'user_token=' . $this->session->data['user_token'] . $url . '&page={page}', true);
+
+ $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('marketplace/modification/clearlog', 'user_token=' . $this->session->data['user_token'], true);
+
+ $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('marketplace/modification', $data));
+ }
+
+ protected function validate() {
+ if (!$this->user->hasPermission('modify', 'marketplace/modification')) {
+ $this->error['warning'] = $this->language->get('error_permission');
+ }
+
+ return !$this->error;
+ }
+}