Completed
Push — master ( 115aec...11e20f )
by Jack
02:31
created

GitHubModule::push()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 8.439
c 0
b 0
f 0
cc 5
eloc 22
nc 5
nop 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 13 and the first side effect is on line 11.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * does everything with one module
5
 *
6
 * see https://github.com/cpliakas/git-commsWrapper for info on the git commsWrapper module
7
 */
8
9
10
use GitWrapper\GitWrapper;
11
require_once '../vendor/autoload.php';
12
13
class GitHubModule extends DataObject {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
14
15
16
17
    /**
18
     * e.g.
19
     * @var string
20
     */
21
    private static $github_account_base_url = '';
22
23
    /**
24
     * e.g. boss
25
     * @var string
26
     */
27
    private static $github_user_name = '';
28
29
    /**
30
     *
31
     *
32
     * @var GitcommsWrapper
33
     */
34
    private static $git_user_email = '';
35
36
    /**
37
     * where the git module is temporary
38
     * cloned and fixed up
39
     * should be an absolute_path
40
     *
41
     * @var string
42
     */
43
    private static $path_to_private_key = '';
44
45
    /**
46
     * where the git module is temporary
47
     * cloned and fixed up
48
     * should be an absolute_path
49
     *
50
     * @var string
51
     */
52
    private static $absolute_temp_folder = '';
53
54
    /**
55
     * wrapper also relates to one git hub repo only!!!!
56
     *
57
     * @var GitcommsWrapper
58
     */
59
    protected $commsWrapper = null;
60
61
    /**
62
     *
63
     *
64
     * @var git module
65
     */
66
    protected $gitRepo = null;
67
68
    private static $db = array (
69
        'ModuleName' => 'VarChar(100)',
70
        'Description' => 'VarChar(300)'
71
    );
72
73
74
    private static $indexes = array (
75
        'ModuleName' => true,
76
    );
77
78
79
    private static $casting = array(
80
        'Directory' => 'Varchar(255)',
81
        'URL' => 'Varchar(255)',
82
    );
83
84
    public function getDirectory() {
85
        return $this->Directory();
86
    }
87
88
    public function getDescription() {
89
        return $this->Description();
90
    }
91
    /**
92
     * absolute path
93
     * @return string | null
94
     */
95
    public function Directory () {
96
        $tempFolder = $this->Config()->get('absolute_temp_folder');
97
        if($this->ModuleName) {
98
            $folder = $tempFolder.'/'.$this->ModuleName;
99
            if(file_exists($folder)) {
100
                if(file_exists($folder)) {
101
                    return $folder;
102
                }
103
            } else {
104
                mkdir($folder);
105
                if(file_exists($folder)) {
106
                    return $folder;
107
                }
108
            }
109
        }
110
    }
111
112
    public function getURL()
113
    {
114
        return $this->URL();
115
    }
116
117
118
    function LongModuleName()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
119
    {
120
        return $this->Config()->get('git_user_name').'/'.$this->ModuleName;
121
    }
122
123
124
    function MediumModuleName()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
125
    {
126
        return $this->ModuleName;
127
    }
128
129
    /**
130
     * @todo: check that silverstripe- is at the start of string.
131
     * @return string
132
     */
133
    function ShortModuleName()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
134
    {
135
        return str_replace('silverstripe-', '', $this->ModuleName);
136
    }
137
138
    function ShortUCFirstName()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
139
    {
140
		$array = explode ('_', $this->ShortModuleName());
141
142
		$name = '';
143
		
144
        foreach ($array as $part) 
145
        {
146
147
			$name .= ucfirst ($part);
148
			
149
		}
150
        
151
        return $name;
152
    }
153
154
155
    function ModuleNameFirstLetterCapital() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
156
        $shortName = $this->ShortModuleName();
157
158
        $firstLetterCapitalName = str_replace ('_', ' ', $shortName);
159
        $firstLetterCapitalName = str_replace ('-', ' ', $firstLetterCapitalName);
160
161
162
        return strtolower ($firstLetterCapitalName);
163
    }
164
165
    function setDescription($str) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
166
        $this->Description = trim($str);
167
    }
168
169
    /**
170
     * check if URL exists and returns it
171
     * @var string | null
172
     */
173
    public function URL () {
174
        $username = $this->Config()->get('git_user_name');
175
        return 'https://github.com/'.$username.'/'.$this->ModuleName;
176
    }
177
178
    protected function IsDirGitRepo ($directory) {
179
        return file_exists($directory."/.git");
180
    }
181
182
183
    /**
184
     *
185
     * @param bool (optional) $forceNew - create a new repo and ditch all changes
186
     * @return Git Repo Object
187
     */
188
    public function checkOrSetGitCommsWrapper($forceNew = false) {
189
        //check if one has been created already...
190
        if( ! $this->gitRepo ) {
191
192
            //basic check
193
            if ($this->ModuleName == '') {
194
                user_error('ModuleName element must be set before using git repository commands');
195
            }
196
197
            //create comms
198
            $this->commsWrapper = new GitWrapper();
199
200
            // Stream output of subsequent Git commands in real time to STDOUT and STDERR.
201
            if(Director::is_cli()) {
202
                $this->commsWrapper->streamOutput();
203
            }
204
205
206
            if( ! $this->Config()->get('path_to_private_key')) {
207
                user_error("We recommend you set private key");
208
            }
209
            // Optionally specify a private key other than one of the defaults.
210
            $this->commsWrapper->setPrivateKey($this->Config()->get('path_to_private_key'));
211
212
            //if directory exists, return existing repo,
213
            //otherwise clone it....
214
            if($this->IsDirGitRepo($this->Directory())) {
215
                if($forceNew) {
216
                    $this->removeClone();
217
                    return $this->checkOrSetGitCommsWrapper(false);
218
                }
219
                $this->gitRepo = $this->commsWrapper->workingCopy($this->Directory());
220
            } else {
221
                GeneralMethods::output_to_screen("cloning ... ".$this->fullGitURL(),'created');
222
223
                $this->gitRepo = null;
224
                $cloneAttempts = 0;
225
                while ( ! $this->gitRepo ) {
226
                    $cloneAttempts ++;
227
                    if ($cloneAttempts == 4) {
228
                        user_error ('Failed to clone module ' . $this->LongModuleName() . ' after ' . ($cloneAttempts  - 1). ' attemps.', E_USER_ERROR);
229
                        //UpdateModules::$unsolvedItems[$this->ModuleName()] = 'Failed to clone modules';
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
230
                        UpdateModules::addUnsolvedProblem($this->ModuleName() , 'Failed to clone modules');
231
                        
232
                    }
233
                    try {
234
                        $this->commsWrapper->setTimeout(240); //Big modules need a longer timeout
235
                        $this->gitRepo = $this->commsWrapper->cloneRepository(
236
                            $this->fullGitURL(),
237
                            $this->Directory()
238
                        );
239
                        $this->commsWrapper->setTimeout(60);
240
                    }
241
                    catch (Exception $e) {
242
                        if (strpos($e->getMessage(), 'already exists and is not an empty directory') !== false) {
243
                            user_error ($e->getMessage(), E_USER_ERROR);
244
                        }
245
246
                        GeneralMethods::outputToScreen ('<li>Failed to clone repository: ' .  $e->getMessage() . '</li>');
247
                        GeneralMethods::outputToScreen ('<li>Waiting 8 seconds to try again ...: </li>');
248
                        $this->removeClone();
249
                        sleep (8);
250
                    }
251
                }
252
            }
253
            $this->gitRepo->config("push.default", "simple");
254
            $this->gitRepo->config("user.name", $this->Config()->get('git_user_name'));
255
            $this->gitRepo->config("user.email", $this->Config()->get('git_user_email'));
256
            $this->commsWrapper->git('config -l');
257
        }
258
        return $this->gitRepo;
259
    }
260
261
    /**
262
     * @var string
263
     */
264
    function fullGitURL()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
265
    {
266
        $username = $this->Config()->get('git_user_name');
267
        $gitURL = $this->Config()->get('github_account_base_url');
268
        return '[email protected]:/'.$username.'/'.$this->ModuleName.'.git';
269
    }
270
271
    /**
272
     * pulls a git repo
273
     *
274
     * @return bool | this
275
     */
276
    public function pull() {
277
        $git = $this->checkOrSetGitCommsWrapper();
278
        if ($git) {
279
            try {
280
                 $git->pull();
281
            }
282
            catch (GitWrapper\GitException $e) {
283
                print_r($e);
284
                throw $e;
285
            }
286
287
288
            //GeneralMethods::output_to_screen($git->getOutput());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
289
            return $this;
290
        }
291
        return false;
292
    }
293
294
    /**
295
     * commits a git repo
296
     *
297
     * @param string $message
298
     *
299
     * @return bool | this
300
     */
301
    public function commit($message = 'PATCH: module clean-up') {
302
303
        $git = $this->checkOrSetGitCommsWrapper();
304
        if ($git) {
305
306
            try {
307
                $git->commit($message);
308
            }
309
            catch (Exception $e) {
310
                $errStr = $e->getMessage();
311
                if (stripos($errStr, 'nothing to commit') === false) {
312
                    print_r($e);
313
                    throw $e;
314
                }
315
                else {
316
                    GeneralMethods::output_to_screen('No changes to commit');
317
                }
318
            }
319
            //GeneralMethods::output_to_screen($git->getOutput());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
320
321
            return $this;
322
        }
323
        return false;
324
    }
325
326
    /**
327
     * adds all files to a git repo
328
     * @return bool | this
329
     */
330
    public function add() {
331
332
        GeneralMethods::output_to_screen('Adding new files to '.$this->ModuleName.' ...  ' ,"created");
333
334
        $git = $this->checkOrSetGitcommsWrapper();
335
        if ($git) {
336
            try {
337
                $git->add(".");
338
            }
339
            catch (GitWrapper\GitException $e) {
340
                $errStr = $e->getMessage();
341
                if (stripos($errStr, 'did not match any files') === false) {
342
                    print_r($e);
343
                    throw $e;
344
                }
345
                else {
346
                   GeneralMethods::output_to_screen('No new files to add to $module. ');
347
                }
348
            }
349
350
            //GeneralMethods::output_to_screen($git->getOutput());
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
351
352
            return $this;
353
        }
354
        return false;
355
    }
356
357
    /**
358
     * adds all files to a git repo
359
     *
360
     * @return bool | this
361
     */
362
    public function push() {
363
        GeneralMethods::output_to_screen('Pushing files to '.$this->ModuleName.' ...  ' ,"created");
364
365
        $git = $this->checkOrSetGitcommsWrapper();
366
        if ($git) {
367
            $pushed = false;
368
            $pushAttempts = 0;
369
            while ( ! $pushed ) {
370
                $pushAttempts ++;
371
                try {
372
                    $git->push();
373
                    $pushed = true;
374
                }
375
                catch (Exception $e) {
376
377
                    if ($pushAttempts == 3) {
378
                        $git->getOutput();
379
                        print_r($e);
380
                        throw $e;
381
                    }
382
                    else {
383
                        GeneralMethods::outputToScreen ('<li>Failed to push repository: ' .  $e->getMessage() . '</li>');
384
                        GeneralMethods::outputToScreen ('<li>Waiting 8 seconds to try again ...: </li>');
385
                        sleep (8);
386
                    }
387
                }
388
            }
389
            return $this;
390
        }
391
        return false;
392
    }
393
394
    /**
395
     * removes a cloned repo
396
     *
397
     *
398
     */
399
    public function removeClone() {
400
        $dir = $this->Directory();
401
        GeneralMethods::output_to_screen('Removing '.$dir.' and all its contents ...  ' ,"created");
402
        $this->gitRepo = null;
403
        FileSystem::removeFolder($dir); // removes contents but not the actual folder
404
        //rmdir ($dir);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
405
        return ! file_exists($dir);
406
    }
407
408
    /**
409
     * retrieves a raw file from Github
410
     *
411
     * @return string | bool
412
     */
413
414
    public function getRawFileFromGithub($fileName) {
415
416
        $gitUserName = $this->Config()->get('git_user_name');
417
        $branch = 'master';
418
419
        $rawURL = 'https://raw.githubusercontent.com/' . $gitUserName . '/' . $this->ModuleName . '/' . $branch . '/' . $fileName;
420
421
        set_error_handler(array($this, 'catchFopenWarning'), E_WARNING);
422
        $file = fopen($rawURL, 'r');
423
        restore_error_handler();
424
425
        if ( ! $file){
426
            GeneralMethods::outputToScreen('<li>Could not find ' . $rawURL . '</li>');
427
            return false;
428
        }
429
        $content = '';
430
        while(! feof($file))
431
        {
432
            $content .= fgets($file);
433
        }
434
        fclose($file);
435
        return $content;
436
    }
437
438
    /*
439
     * This function is just used to suppression of warnings
440
     * */
441
    private function catchFopenWarning($errno, $errstr) {
442
        //
443
    }
444
445
446
    public static function get_or_create_github_module($moduleName) {
447
        $moduleName = trim($moduleName);
448
        $filter = array('ModuleName' => $moduleName);
449
        $gitHubModule = GitHubModule::get()->filter($filter)->first();
450
        if ( ! $gitHubModule) {
451
            $gitHubModule = GitHubModule::create($filter);
452
            $gitHubModule->write();
453
        }
454
455
        return $gitHubModule;
456
    }
457
458
459
    public function getLatestCommitTime() {
460
        // equivalent to git log -1 --format=%cd .
461
462
        $git = $this->checkOrSetGitCommsWrapper();
463
        if ($git) {
464
            $options = array (
465
                'format' => "%cd",
466
                '1' => true
467
            );
468
			
469
			try {
470
            $result = $git->log ($options);
471
			}
472
			catch (Exception $e) {
473
				$errStr = $e->getMessage();
474
                if (stripos($errStr, 'does not have any commits') === false) {
475
                    print_r($e);
476
                    throw $e;
477
                }
478
                else {
479
                    
480
                    return false;
481
                }
482
			}            
483
            
484
            if ($result) {
485
                return (strtotime($result));
486
            }
487
            else {
488
                return false;
489
            }
490
        }
491
        else {
492
            return false;
493
        }
494
    }
495
496
    public function getLatestTag() {
497
        $git = $this->checkOrSetGitCommsWrapper();
498
        if ($git) {
499
            $options = array (
500
                'tags' => true,
501
                'simplify-by-decoration' => true,
502
                'pretty' => 'format:%ai %d'
503
            );
504
505
            $cwd = getcwd();
506
            chdir($this->Directory);
507
508
			try {
509
				$result = $git->log($options);
510
			}
511
			catch (Exception $e) {
512
				$errStr = $e->getMessage();
513
                if (stripos($errStr, 'does not have any commits') === false) {
514
                    print_r($e);
515
                    throw $e;
516
                }
517
                else {
518
                    GeneralMethods::output_to_screen('Unable to get tag because there are no commits to the repository');
519
                    return false;
520
                }
521
			}
522
523
524
            chdir($cwd);
525
526
            $resultLines  =  explode ("\n", $result->getOutput());
527
528
            // 2016-10-14 12:29:08 +1300 (HEAD -> master, tag: 2.3.0, tag: 2.2.0, tag: 2.1.0, origin/master, origin/HEAD)\
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
529
            // or
530
            // 2016-08-29 17:18:22 +1200 (tag: 2.0.0)
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
531
            //print_r($resultLines);
532
533
534
            if (count($resultLines) == 0) {
535
                return false;
536
            }
537
538
            $latestTimeStamp = 0;
539
            $latestTag = false;
540
            foreach ($resultLines as $line) {
541
                $isTagInLine = (strpos ($line, 'tag') !== false);
542
                if ($isTagInLine) {
543
                    $tagStr = trim(substr($line, 25));
544
                    $dateStr = trim(substr($line, 0, 26));
545
546
547
                    //extract tag numbers from $tagStr
548
549
                    $matches = array();
550
                    // print_r ("original!!! " .  $tagStr);
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
551
                    $result = preg_match_all('/tag: \d{1,3}.\d{1,3}.\d{1,3}/', $tagStr, $matches);
552
                    if ($result === false)
553
                    {
554
                        continue;
555
                    }
556
                    elseif ($result > 1)
557
                    {
558
                        $tagStr = $matches[0][0];
559
                    }
560
                    //print_r ($matches);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
561
562
                    $tagStr  = str_replace('(', '', $tagStr);
563
                    $tagStr  = str_replace(')', '', $tagStr);
564
                    $timeStamp = strtotime ($dateStr);
565
566
                    if ($latestTimeStamp < $timeStamp) {
567
                        $latestTimeStamp = $timeStamp;
568
                        $latestTag = $tagStr;
569
                    }
570
                }
571
            }
572
573
        }
574
575
        if (isset($latestTag) && $latestTag) {
576
            $latestTag = str_replace('tag:', '', $latestTag) ;
577
578
579
            $tagParts = explode ('.', $latestTag);
580
581
            if (count($tagParts) != 3) return false;
582
583
            return array (
584
                'tagstring' => $latestTag,
585
                'tagparts' => $tagParts,
586
                'timestamp' => $latestTimeStamp);
587
588
        }
589
        else {
590
            return false;
591
        }
592
    }
593
594
    public function createTag($tagCommandOptions)
595
    {
596
        $this->gitRepo->tag($tagCommandOptions);
597
        $this->gitRepo->push(array('tags' => true));
598
599
    }
600
601
    public function updateGitHubInfo($array) {
602
        // see https://developer.github.com/v3/repos/#edit
603
        $defaultValues =array(
604
            'name' => $this->LongModuleName(),
605
            'private' => false,
606
            'has_wiki' => false,
607
            'has_issues' => true,
608
            'has_downloads' => true,
609
            'homepage' => 'http://ssmods.com/'
610
            );
611
612
        if ($this->Description) {
613
            $array['description'] = $this->Description;
614
        }
615
616
        foreach ($defaultValues as $key=>$value) {
617
            if (! isset($array[$key])) {
618
                $array[$key]  = $value;
619
            }
620
        }
621
622
        GeneralMethods::OutputToScreen('updating Git Repo information ...');
623
624
        $this->gitApiCall($array, '',  'PATCH');
625
    }
626
627
    protected function gitApiCall($data, $gitAPIcommand = '', $method = 'GET') {
628
        $jsonData = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
629
        GeneralMethods::OutputToScreen('Running Git API command ' .$gitAPIcommand. ' using ' .$method. ' method...');
630
        $gitUserName = $this->Config()->get('git_user_name');
631
        $url = 'https://api.github.com/:repos/' . trim($gitUserName) . '/:' . trim($this->ModuleName);
632
        if (trim($gitAPIcommand)) {
633
            $url .= '/' . trim($gitAPIcommand);
634
        }
635
        $method = trim(strtoupper($method));
636
        $ch = curl_init($url);
637
        $header = "Content-Type: application/json";
638
        if ($method == 'GET') {
639
            $url .= '?'.http_build_query($data);
640
        }
641
        $gitApiUserName = trim($this->Config()->get('git_api_login_username'));
642
        $gitApiUserPassword = trim($this->Config()->get('git_api_login_password'));
643
        $gitApiAccessToken = trim($this->Config()->get('git_personal_access_token'));
644
        if (trim($gitApiAccessToken)) {
645
            $gitApiUserPassword = $gitApiAccessToken;
646
        }
647
        curl_setopt($ch, CURLOPT_VERBOSE, 1);
648
        curl_setopt($ch, CURLOPT_URL, $url);
649
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
650
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
651
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
652
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
653
        curl_setopt($ch, CURLOPT_USERAGENT,
654
            'Silverstripe-update-module-module');
655
        if (isset($gitApiUserName) && isset($gitApiUserPassword)) {
656
            curl_setopt($ch, CURLOPT_USERPWD, $gitApiUserName . ':' . $gitApiUserPassword);
657
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
658
        }
659
        if ($method == 'POST' ) {
660
            curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
661
        }
662
        $curlResult = curl_exec($ch);
663
        if ( ! $curlResult ){
664
			$msg = "curl exectution failed";
665
            GeneralMethods::outputToScreen ($msg);
666
			UpdateModules::$unsolvedItems["none"] = $msg;
667
        }
668
        print_r($url);
669
        print_r('<br/>');
670
        print_r($curlResult );
671
        die();
672
        return $curlResult;
673
    }
674
    
675
    
676
	public static function getRepoList() {
677
		
678
679
        $gitUserName = GitHubModule::Config()->get('git_user_name');
680
        $url = 'https://api.github.com/users/' . trim($gitUserName) . '/repos';
681
		$array  = array();
682
		for($page = 0; $page < 10; $page++) {
683
		
684
			$data = array(
685
				'per_page' => 100,
686
				'page'=>$page
687
			);
688
689
			$method = 'GET';
690
			$ch = curl_init($url);
691
			$header = "Content-Type: application/json";
692
693
			if ($method == 'GET') {
694
				$url .= '?'.http_build_query($data);
695
			}
696
697
			$gitApiUserName = trim(GitHubModule::Config()->get('git_api_login_username'));
698
			$gitUserName = trim(GitHubModule::Config()->get('git_user_name'));
699
			$gitApiUserPassword = trim(GitHubModule::Config()->get('git_api_login_password'));
700
701
			$gitApiAccessToken = trim(GitHubModule::Config()->get('git_personal_access_token'));
702
			if (trim($gitApiAccessToken)) {
703
				$gitApiUserPassword = $gitApiAccessToken;
704
			}
705
706
707
			curl_setopt($ch, CURLOPT_VERBOSE, 1);
708
			curl_setopt($ch, CURLOPT_URL, $url);
709
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
710
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
711
			curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
712
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
713
			curl_setopt($ch, CURLOPT_USERAGENT,
714
				'sunnysideupdevs');
715
716
717
			if (isset($gitApiUserName) && isset($gitApiUserPassword)) {
718
				curl_setopt($ch, CURLOPT_USERPWD, $gitApiUserName . ':' . $gitApiUserPassword);
719
				curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
720
			}
721
722
723
			$curlResult = curl_exec($ch);
724
725
			if ( ! $curlResult ){
726
				GeneralMethods::OutputToScreen('Could not retrieve list of modules from GitHub');
727
\
728
				UpdateModules::$unsolvedItems[$"all"] =  ('Could not retrieve list of modules from GitHub');
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting T_VARIABLE or '{' or '$'
Loading history...
729
				die ('');
730
			}
731
			
732
			$array = array_merge( $array, json_decode($curlResult));
733
		}
734
735
		
736
		$modules = array();
737
		
738
		if(count($array) > 0 )
739
		
740
		 {
741
                    foreach($array as $repo) {
742
						
743
						// see http://stackoverflow.com/questions/4345554/convert-php-object-to-associative-array
744
						$repo = json_decode(json_encode($repo), true);
745
746
747
                        //dont bother about forks
748
                        if(isset($repo["fork"]) && !$repo["fork"]) {
749
                            //make sure we are the owners
750
751
                            if($repo["owner"]["login"] == $gitUserName) {
752
753
                                $isSSModule =  ( stripos($repo["name"], 'silverstripe-')  !== false );
754
                                //check it is silverstripe module
755
                                $getNamesWithPrefix = false;
756
                                
757
                                if (!$getNamesWithPrefix) {
758
                                    $name = $repo["name"];                                    
759
                                }
760
                                else {
761
                                    $name = preg_replace('/silverstripe/', "", $repo["name"], $limit = 1);                                    
762
                                }
763
                                
764
                                //if(strlen($name) < strlen($repo["name"])) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
765
                                if($isSSModule) {
766
                                    //is it listed yet?
767
                                    if(!in_array($name, $modules)) {
768
										
769
                                        array_push ($modules, $name);
770
                                    }
771
                                }
772
                                else {
773
                                    GeneralMethods::OutputToScreen("skipping ".$repo["name"]." as it does not appear to me a silverstripe module");
774
                                }
775
                            }
776
                            else {
777
                                GeneralMethods::OutputToScreen("skipping ".$repo["name"]." as it has a different owner");
778
                            }
779
                        }
780
                        elseif(isset($repo["name"])) {
781
                            DB::alteration_message("skipping ".$repo["name"]." as it is a fork");
782
                        }
783
                    }
784
                }
785
786
        return $modules;
787
    }
788
789
    public function addRepoToScrutinzer () {
790
791
        if (! trim($this->Config()->get('scrutinizer_api_key'))) {
792
            GeneralMethods::outputToScreen ("<li> not Scrutinizer API key set </li>");
793
            return false;
794
        }
795
796
        //see https://scrutinizer-ci.com/docs/api/#repositories
797
        $scrutinizerApiPath = "https://scrutinizer-ci.com/api";
798
        $endPoint = "repositories/g?access_token=" . trim($this->Config()->get('scrutinizer_api_key'));
799
        $url = $scrutinizerApiPath . "/" . $endPoint;
800
        $username = $this->Config()->get('git_user_name');
801
        $repoName =  $username.'/'.$this->ModuleName;
802
803
804
        $postFields = array (
805
            'name' => $repoName,
806
            );
807
808
        $ch = curl_init($url);
809
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
810
811
        curl_setopt($ch, CURLOPT_URL, $url);
812
        curl_setopt($ch,CURLOPT_POST, count($postFields));
813
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
814
815
816
        $curlResult = curl_exec($ch);
817
818
        if ( ! $curlResult ){
819
            GeneralMethods::outputToScreen ("<li> could not add $repoName to Scrutinizer ... </li>");
820
            //UpdateModules::$unsolvedItems[$repoName] = "Could not add $reopName to Scrutiniser (curl failure)";
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
821
            
822
            UpdateModules::addUnsolvedProblem($repoName, "Could not add $reopName to Scrutiniser (curl failure)");
823
            
824
            return false;
825
        }
826
827
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
828
829
830
        if ($httpcode == 201) {
831
            GeneralMethods::outputToScreen ("<li> Added $repoName to Scrutinizer ... </li>");
832
        }
833
        else{
834
            GeneralMethods::outputToScreen ("<li> could not add $repoName to Scrutinizer ... </li>");
835
            //UpdateModules::$unsolvedItems[$repoName] = "Could not add $reopName to Scrutiniser (HttpCode $httpcode)";
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
836
            UpdateModules::addUnsolvedProblem($repoName, "Could not add $reopName to Scrutiniser (HttpCode $httpcode)");
837
        }
838
839
840
841
    }
842
843
844
845
846
}
847