├── .gitignore
├── LICENSE.md
├── README.md
└── gitplugins
├── GitPluginsPlugin.php
├── controllers
└── GitPlugins_GetController.php
├── resources
└── icon.svg
├── services
└── GitPlugins_GetService.php
├── templates
└── GitPluginsWidget.html
└── widgets
└── GitPlugins_GitWidget.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Anata Creative
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gitPlugins
2 |
3 | Get your plugins from Github straight into your Craft CMS.
4 |
5 |
6 | ## Installation
7 |
8 | 1. Download and extract the contents of the zip. Put the `gitplugins` folder to your Craft plugin folder.
9 | 2. Enable the gitPlugins plugin in Craft (Settings > Plugins).
10 | 3. Add the widget to your dashboard (Dashboard > New widget > Download Github Plugins).
11 |
12 |
13 | ## Usage
14 | 1. Get the base-url (for example: https://github.com/AnataCreative/gitPlugins) or zip-url (for example: https://github.com/AnataCreative/gitPlugins/archive/master.zip) for your plugin on Github.
15 | 2. Paste it in the input-field and click get.
16 | 3. The plugin will be downloaded and put into your plugins-folder.
17 | 4. Go to the plugins page (Settings > Plugins) and install your downloaded plugin.
18 | 5. Be awesome! :fire:
19 |
20 |
21 | ## Credits
22 | This plugin has started from the plugin uploader (https://github.com/yatryan/craft-plugin-uploader), and still has some parts of it in it. So big thanks to Taylor Ryan for that!
23 |
24 |
25 | ## Contribution
26 | Want to contribute or fix a bug? Awesome! :heart_eyes_cat:
27 | Just make a pull request to the develop branch and provide some explanation.
28 |
29 | If you are fixing a bug or adding an enhancement, please assign the issue to yourself, so people will know you're working on it.
30 |
31 |
32 | ## Roadmap
33 | Look for the issues with the tag 'enhancement'. Help is always welcome! :blush:
34 |
--------------------------------------------------------------------------------
/gitplugins/GitPluginsPlugin.php:
--------------------------------------------------------------------------------
1 | _name);
21 | }
22 |
23 | public function getUrl()
24 | {
25 | return $this->_url;
26 | }
27 |
28 | public function getVersion()
29 | {
30 | return $this->_version;
31 | }
32 |
33 | public function getDeveloper()
34 | {
35 | return $this->_developer;
36 | }
37 |
38 | public function getDeveloperUrl()
39 | {
40 | return $this->_developerUrl;
41 | }
42 |
43 | public function getDescription()
44 | {
45 | return $this->_description;
46 | }
47 |
48 | public function getDocumentationUrl()
49 | {
50 | return $this->_documentationUrl;
51 | }
52 |
53 | public function getSchemaVersion()
54 | {
55 | return $this->_schemaVersion;
56 | }
57 |
58 | public function getReleaseFeedUrl()
59 | {
60 | return $this->_releaseFeedUrl;
61 | }
62 |
63 | public function getCraftRequiredVersion()
64 | {
65 | return $this->_minVersion;
66 | }
67 |
68 | public function onBeforeInstall()
69 | {
70 | if (!file_exists('../craft/storage/uploads/gitPlugins')) {
71 | mkdir('../craft/storage/uploads/gitPlugins', 0777, true);
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/gitplugins/controllers/GitPlugins_GetController.php:
--------------------------------------------------------------------------------
1 | request->getPost('url');
9 |
10 | $error = craft()->gitPlugins_get->getPlugin($url);
11 |
12 | if ($error) {
13 | craft()->userSession->setNotice(Craft::t($error));
14 | } else {
15 | craft()->userSession->setNotice(Craft::t('Plugin downloaded'));
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/gitplugins/resources/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/gitplugins/services/GitPlugins_GetService.php:
--------------------------------------------------------------------------------
1 | checkUrl($url);
20 |
21 | // Return
22 | return $error;
23 | }
24 |
25 |
26 |
27 | /**
28 | * @param string $url
29 | */
30 | public function checkUrl($url)
31 | {
32 | // Is Github url?
33 | if (strpos($url, 'github') === false) {
34 | $error = 'Please enter a Github URL';
35 | return $error;
36 | }
37 |
38 | // Determin Download Url
39 | if (strpos($url, '.zip')) {
40 | // Set
41 | $downloadUrl = $url;
42 | } else {
43 | // Set
44 | $downloadUrl = $url;
45 |
46 | if (substr($url, -1) !== '/') {
47 | $downloadUrl = $downloadUrl.'/';
48 | }
49 |
50 | $downloadUrl = $downloadUrl.'archive/master.zip';
51 | }
52 |
53 | // Get filename
54 | $http_response_header = get_headers($url);
55 | $realfilename = $this->get_real_filename($http_response_header, $url);
56 |
57 | // Determin Ziptarget and folderTarget
58 | if (strpos($realfilename, '.zip')) {
59 | $zipTarget = UPLOAD_FOLDER.'/'.$realfilename;
60 | } else {
61 | $zipTarget = UPLOAD_FOLDER.'/'.$realfilename.'-master.zip';
62 | }
63 |
64 | $folderTarget = str_replace('.zip', '', $zipTarget);
65 |
66 | // Download
67 | $error = $this->download($zipTarget, $folderTarget, $downloadUrl);
68 |
69 | // return
70 | return $error;
71 | }
72 |
73 |
74 |
75 | /**
76 | * @param string $zipTarget
77 | * @param string $folderTarget
78 | * @param string $downloadUrl
79 | */
80 | public function download($zipTarget, $folderTarget, $downloadUrl)
81 | {
82 | $file = @file_get_contents($downloadUrl);
83 |
84 | if ($file) {
85 | if (!is_dir(UPLOAD_FOLDER)) {
86 | $error = "Upload folder doesn't exist";
87 | } else if (!is_writable(UPLOAD_FOLDER)) {
88 | $error = "Can't write plugin to the upload folder";
89 | } else {
90 | file_put_contents($zipTarget, $file);
91 |
92 | $error = $this->extract($zipTarget, $folderTarget);
93 | }
94 | } else {
95 | $error = "Can't download plugin";
96 | }
97 |
98 | return $error;
99 | }
100 |
101 |
102 | /**
103 | * @param string $zipTarget
104 | * @param string $folderTarget
105 | */
106 | public function extract($zipTarget, $folderTarget)
107 | {
108 | $date = new DateTime();
109 | $now = $date->getTimestamp();
110 | $zip = new \ZipArchive();
111 | $res = $zip->open($zipTarget);
112 |
113 | if ($res === TRUE) {
114 | $zip->extractTo(UPLOAD_FOLDER);
115 | $zip->close();
116 |
117 | $error = $this->move($folderTarget, $zipTarget);
118 | } else {
119 | $error = "Can't extract zip";
120 | }
121 |
122 | return $error;
123 | }
124 |
125 |
126 | /**
127 | * @param string $uploadFolder
128 | * @param string $uploadZipFile
129 | */
130 | public function move($uploadFolder, $uploadZipFile)
131 | {
132 | $pluginExtractFile = '';
133 | $pluginExtractFolder = '';
134 |
135 | // Find the folder that the Plugin.php file is in. That is the root of the plugin.
136 | foreach (glob($uploadFolder."/*Plugin.php") as $filename) {
137 | $pluginExtractFile = $filename;
138 | $pluginExtractFolder = dirname($filename);
139 | }
140 |
141 | if ($pluginExtractFile === '') {
142 | foreach (glob($uploadFolder."/**/*Plugin.php") as $filename) {
143 | $pluginExtractFile = $filename;
144 | $pluginExtractFolder = dirname($filename);
145 | }
146 | }
147 |
148 | // Open the file
149 | $fp = @fopen($pluginExtractFile, 'r');
150 | if ($fp) {
151 | $array = explode("\n", fread($fp, filesize($pluginExtractFile)));
152 |
153 | $pluginName = '';
154 |
155 | // Get name of plugin
156 | foreach ($array as $line) {
157 | if (strpos($line, 'class') !== false && strpos($line, 'extends') !== false) {
158 | $split = explode(" ", $line);
159 | $pluginName = substr($split[1], 0, -6);
160 | break;
161 | }
162 | }
163 |
164 | // Copy to craft/plugins folder.
165 | $pluginInstallFolder = CRAFT_PLUGIN_FOLDER.'/'.strtolower($pluginName);
166 |
167 | if (!file_exists($pluginInstallFolder)) {
168 | // Copy folder to craft/plugins
169 | $this->recurse_copy($pluginExtractFolder, $pluginInstallFolder);
170 |
171 | $error = false;
172 | }
173 | else {
174 | $error = 'The plugin "'.$pluginName.'" is already uploaded.';
175 | }
176 | } else {
177 | $error = 'The uploaded file is not a valid plugin.';
178 | }
179 |
180 | // Remove zipfile and folder from uploads
181 | $this->rrmdir($uploadFolder);
182 | unlink($uploadZipFile);
183 |
184 | return $error;
185 | }
186 |
187 |
188 | /**
189 | * @param string $dir
190 | */
191 | private function rrmdir($dir)
192 | {
193 | foreach (glob($dir.'/{,.}[!.,!..]*', GLOB_MARK|GLOB_BRACE) as $file) {
194 | if (is_dir($file)) {
195 | $this->rrmdir($file);
196 | } else {
197 | unlink($file);
198 | }
199 | }
200 | rmdir($dir);
201 | }
202 |
203 |
204 | /**
205 | * @param string $src
206 | * @param string $dst
207 | */
208 | private function recurse_copy($src, $dst)
209 | {
210 | $dir = opendir($src);
211 | @mkdir($dst);
212 |
213 | while(false !== ( $file = readdir($dir)) ) {
214 | if (( $file != '.' ) && ( $file != '..' )) {
215 | if ( is_dir($src . '/' . $file) ) {
216 | $this->recurse_copy($src . '/' . $file,$dst . '/' . $file);
217 | } else {
218 | copy($src . '/' . $file,$dst . '/' . $file);
219 | }
220 | }
221 | }
222 |
223 | closedir($dir);
224 | }
225 |
226 |
227 | /**
228 | * @param string $to
229 | */
230 | protected function move_uploaded_file($from, $to)
231 | {
232 | return move_uploaded_file($from, $to);
233 | }
234 |
235 |
236 | /**
237 | * @param string $headers
238 | * @param string $url
239 | */
240 | protected function get_real_filename($headers, $url)
241 | {
242 | foreach($headers as $header)
243 | {
244 | if (strpos(strtolower($header),'content-disposition') !== false)
245 | {
246 | $tmp_name = explode('=', $header);
247 | if ($tmp_name[1]) {
248 | return trim($tmp_name[1],'";\'');
249 | }
250 | }
251 | }
252 |
253 | $stripped_url = preg_replace('/\\?.*/', '', $url);
254 | return basename($stripped_url);
255 | }
256 | }
257 |
--------------------------------------------------------------------------------
/gitplugins/templates/GitPluginsWidget.html:
--------------------------------------------------------------------------------
1 | {% if not craft.users or craft.users.can('accessPlugin-gitplugin') %}
2 |
3 | {% import "_includes/forms" as forms %}
4 |
5 |
30 |
31 |