├── optimg.png ├── optimg-demo.png ├── .gitignore ├── admin ├── language │ └── en-gb │ │ └── extension │ │ └── module │ │ └── optimg.php ├── view │ └── template │ │ └── extension │ │ └── module │ │ └── optimg.twig └── controller │ └── extension │ └── module │ └── optimg.php └── README.md /optimg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfdesign/Optimg---OpenCart-Image-Optimizer-Compressor/HEAD/optimg.png -------------------------------------------------------------------------------- /optimg-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfdesign/Optimg---OpenCart-Image-Optimizer-Compressor/HEAD/optimg-demo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .htaccess 2 | /config.php 3 | admin/config.php 4 | 5 | !index.html 6 | 7 | download/ 8 | image/data/ 9 | image/cache/ 10 | system/cache/ 11 | system/logs/ 12 | 13 | system/storage/ 14 | -------------------------------------------------------------------------------- /admin/language/en-gb/extension/module/optimg.php: -------------------------------------------------------------------------------- 1 | 3 | 16 |
17 | {% if error_warning %} 18 |
{{ error_warning }} 19 | 20 |
21 | {% endif %} 22 | 25 |
26 |
27 |

{{ text_edit }}

28 |
29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |

Optimised files

{{ optimisedFilesCount }}

Files for optimising

{{ allFilesCount - optimisedFilesCount }}

42 |
43 |
44 |
45 |
46 | 47 | 48 | 49 |
50 |
51 | 52 |
53 | 62 |
63 |
64 |
65 |
66 |
67 |
68 | 69 | 117 | {{ footer }} 118 | -------------------------------------------------------------------------------- /admin/controller/extension/module/optimg.php: -------------------------------------------------------------------------------- 1 | load->language('extension/module/optimg'); 9 | 10 | $this->document->setTitle($this->language->get('heading_title')); 11 | 12 | $this->load->model('setting/setting'); 13 | 14 | if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { 15 | $this->model_setting_setting->editSetting('module_optimg', $this->request->post); 16 | 17 | $this->session->data['success'] = $this->language->get('text_success'); 18 | 19 | $this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true)); 20 | } 21 | 22 | if (isset($this->error['warning'])) { 23 | $data['error_warning'] = $this->error['warning']; 24 | } else { 25 | $data['error_warning'] = ''; 26 | } 27 | 28 | $data['breadcrumbs'] = array(); 29 | 30 | $data['breadcrumbs'][] = array( 31 | 'text' => $this->language->get('text_home'), 32 | 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'], true) 33 | ); 34 | 35 | $data['breadcrumbs'][] = array( 36 | 'text' => $this->language->get('text_extension'), 37 | 'href' => $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true) 38 | ); 39 | 40 | $data['breadcrumbs'][] = array( 41 | 'text' => $this->language->get('heading_title'), 42 | 'href' => $this->url->link('extension/module/optimg', 'user_token=' . $this->session->data['user_token'], true) 43 | ); 44 | 45 | $data['action'] = $this->url->link('extension/module/optimg', 'user_token=' . $this->session->data['user_token'], true); 46 | 47 | $data['cancel'] = $this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true); 48 | 49 | if (isset($this->request->post['module_optimg_status'])) { 50 | $data['module_optimg_status'] = $this->request->post['module_optimg_status']; 51 | } else { 52 | $data['module_optimg_status'] = $this->config->get('module_optimg_status'); 53 | } 54 | 55 | $data['header'] = $this->load->controller('common/header'); 56 | $data['column_left'] = $this->load->controller('common/column_left'); 57 | $data['footer'] = $this->load->controller('common/footer'); 58 | $data['user_token'] = $this->session->data['user_token']; 59 | 60 | $allFilesCount = count(self::getAllImages()); 61 | $optimisedFilesCount = count($this->getOptimisedImages()); 62 | $data['optimisedFilesCount'] = $optimisedFilesCount; 63 | $data['allFilesCount'] = $allFilesCount; 64 | $data['percentage'] = round((($optimisedFilesCount / $allFilesCount) * 100)); 65 | $this->response->setOutput($this->load->view('extension/module/optimg', $data)); 66 | } 67 | 68 | // AJAX call method 69 | public function compress(){ 70 | error_reporting(0); 71 | 72 | $allFiles = self::getAllImages(); 73 | $allFIilesCount = count($allFiles); 74 | $optimisedFiles = $this->getOptimisedImages(); 75 | $optimisedFilesCount = count(--$optimisedFiles); 76 | 77 | $filesForOptimising = array_values(array_diff($allFiles, $optimisedFiles)); 78 | $percentage = round((($optimisedFilesCount / $allFIilesCount) * 100)); 79 | $response['optimisedFiles'] = $optimisedFilesCount; 80 | $response['allFiles'] = $allFIilesCount; 81 | $response['percentage'] = $percentage; 82 | 83 | if($percentage < 100) { 84 | $file = $this->compressImageRequest($filesForOptimising[0]); 85 | if($file) { 86 | if (!copy($file['dest'], realpath(DIR_IMAGE) . $filesForOptimising[0])) { 87 | $response['error'] = 'There is issue uploading file.' . $file; 88 | $this->response->addHeader('Content-Type: application/json'); 89 | $this->response->setOutput(json_encode($response)); 90 | } else { 91 | file_put_contents(DIR_IMAGE . self::DAT_FILE_PATH, $filesForOptimising[0] . '\r\n', FILE_APPEND); 92 | $this->response->addHeader('Content-Type: application/json'); 93 | $this->response->setOutput(json_encode($response)); 94 | } 95 | } 96 | } else { 97 | $response['success'] = 'Files optimised.'; 98 | $this->response->addHeader('Content-Type: application/json'); 99 | $this->response->setOutput(json_encode($response)); 100 | } 101 | } 102 | 103 | protected function compressImageRequest($filePath){ 104 | $file = realpath(DIR_IMAGE . $filePath); 105 | $mime = mime_content_type($file); 106 | $info = pathinfo($file); 107 | $name = $info['basename']; 108 | $output = new CURLFile($file, $mime, $name); 109 | $data = array( 110 | "files" => $output, 111 | ); 112 | 113 | $ch = curl_init(); 114 | curl_setopt($ch, CURLOPT_URL, 'http://api.resmush.it/?qlty=80'); 115 | curl_setopt($ch, CURLOPT_POST, 1); 116 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 117 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 118 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 119 | 120 | $result = curl_exec($ch); 121 | if (curl_errno($ch)) { 122 | $result['error'] = curl_error($ch); 123 | } 124 | curl_close($ch); 125 | return json_decode($result, true); 126 | } 127 | 128 | protected function validate() { 129 | if (!$this->user->hasPermission('modify', 'extension/module/optimg')) { 130 | $this->error['warning'] = $this->language->get('error_permission'); 131 | } 132 | 133 | return !$this->error; 134 | } 135 | 136 | protected static function getAllImages(){ 137 | $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(DIR_IMAGE . 'cache'), RecursiveIteratorIterator::CHILD_FIRST); 138 | $files = []; 139 | 140 | foreach($iterator as $path) { 141 | if($path->isFile()) { 142 | $filename = $path->__toString(); 143 | if(strtolower(pathinfo($filename,PATHINFO_EXTENSION)) ==='jpeg' || 144 | strtolower(pathinfo($filename,PATHINFO_EXTENSION)) === 'jpg' || 145 | strtolower(pathinfo($filename,PATHINFO_EXTENSION)) === 'png'){ 146 | 147 | $files[] = str_replace(realpath(DIR_IMAGE), "", realpath($filename)); 148 | } 149 | } 150 | } 151 | return $files; 152 | } 153 | 154 | protected function getOptimisedImages() { 155 | $cachedFile = DIR_IMAGE . self::DAT_FILE_PATH; 156 | 157 | if(!file_exists($cachedFile)) { 158 | return []; 159 | } 160 | 161 | return explode('\r\n', file_get_contents($cachedFile)); 162 | } 163 | 164 | public function install() { 165 | $datFile = DIR_IMAGE . 'cache/optimised.dat'; 166 | if(!fopen($datFile, 'w')){ 167 | $this->error['warning'] = $this->language->get('writing_file_permission'); 168 | } else { 169 | fclose($datFile); 170 | } 171 | } 172 | 173 | } 174 | --------------------------------------------------------------------------------