1 | <?php namespace App\Command; |
||||
2 | |||||
3 | use Symfony\Component\Console\Input\InputInterface; |
||||
4 | use Symfony\Component\Console\Output\OutputInterface; |
||||
5 | |||||
6 | class GitCommitContentCommand extends Command { |
||||
7 | |||||
8 | private $output; |
||||
9 | |||||
10 | public function getName() { |
||||
11 | return 'git:commit-content'; |
||||
12 | } |
||||
13 | |||||
14 | public function getDescription() { |
||||
15 | return 'Commit content changes from last X minutes'; |
||||
16 | } |
||||
17 | |||||
18 | public function getHelp() { |
||||
19 | return 'The <info>%command.name%</info> command commits all recent content changes.'; |
||||
20 | } |
||||
21 | |||||
22 | protected function getRequiredArguments() { |
||||
23 | return [ |
||||
24 | 'desc' => 'Brief description of changes', |
||||
25 | ]; |
||||
26 | } |
||||
27 | |||||
28 | protected function getOptionalOptions() { |
||||
29 | return [ |
||||
30 | 'from' => ['Number of last minutes to check for changes', 30], |
||||
31 | ]; |
||||
32 | } |
||||
33 | |||||
34 | /** {@inheritdoc} */ |
||||
35 | protected function execute(InputInterface $input, OutputInterface $output): int { |
||||
36 | $this->output = $output; |
||||
37 | |||||
38 | $description = $input->getArgument('desc'); |
||||
39 | $lastMinutes = $input->getOption('from'); |
||||
40 | $fromTime = date('Y-m-d H:i:s', strtotime("-$lastMinutes minutes")); |
||||
41 | $this->commitChanges($this->webDir('content'), $this->createMessageFile($description, $fromTime)); |
||||
42 | |||||
43 | $output->writeln('Done.'); |
||||
44 | return self::SUCCESS; |
||||
45 | } |
||||
46 | |||||
47 | /** |
||||
48 | * @param string $contentDir |
||||
49 | * @param string $messageFile |
||||
50 | */ |
||||
51 | private function commitChanges($contentDir, $messageFile) { |
||||
52 | if ( ! file_exists($messageFile)) { |
||||
53 | throw new \Exception("Message file '$messageFile' does not exist."); |
||||
54 | } |
||||
55 | $finder = new \Symfony\Component\Finder\Finder; |
||||
56 | foreach ($finder->directories()->in($contentDir)->depth(0) as $directory) { |
||||
57 | $this->gitCommitAndPush($directory, $messageFile); |
||||
58 | } |
||||
59 | } |
||||
60 | |||||
61 | /** |
||||
62 | * @param string $directory |
||||
63 | * @param string $messageFile |
||||
64 | */ |
||||
65 | private function gitCommitAndPush($directory, $messageFile) { |
||||
66 | $this->output->writeln(''); |
||||
67 | $this->output->writeln('===> Entering ' . basename($directory)); |
||||
68 | chdir($directory); |
||||
69 | if (strpos(shell_exec('LC_ALL=C git status'), 'nothing to commit') !== false) { |
||||
70 | $this->output->writeln('Nothing to commit'); |
||||
71 | return; |
||||
72 | } |
||||
73 | $this->output->writeln('Pulling eventual changes'); |
||||
74 | shell_exec('git pull'); |
||||
75 | $this->output->writeln('Staging current changes'); |
||||
76 | shell_exec('git add .; git add -u .'); |
||||
77 | $this->output->writeln('Commiting current changes'); |
||||
78 | shell_exec("git commit --file='$messageFile'"); |
||||
79 | $this->output->writeln('Pushing commit to remote server'); |
||||
80 | shell_exec('git push'); |
||||
81 | } |
||||
82 | |||||
83 | /** |
||||
84 | * @param string $description |
||||
85 | * @param string $fromTime |
||||
86 | */ |
||||
87 | private function createMessageFile($description, $fromTime) { |
||||
88 | $filename = sys_get_temp_dir().'/chitanka-commit-content-'.time(); |
||||
89 | file_put_contents($filename, $this->createMessageFileContents($description, $fromTime)); |
||||
90 | return $filename; |
||||
91 | } |
||||
92 | |||||
93 | /** |
||||
94 | * @param string $description |
||||
95 | * @param string $fromTime |
||||
96 | */ |
||||
97 | private function createMessageFileContents($description, $fromTime) { |
||||
98 | $messageId = date('#Ymd.His'); |
||||
99 | $booksChanges = $this->getChangedBooksDescriptions($fromTime); |
||||
100 | $booksMessage = ''; |
||||
101 | if (count($booksChanges) > 0) { |
||||
102 | $booksMessage .= count($booksChanges) == 1 ? 'Book:' : 'Books:'; |
||||
103 | $booksMessage .= "\n" . implode("\n", $booksChanges); |
||||
104 | } |
||||
105 | |||||
106 | $textsChanges = $this->getChangedTextsDescriptions($fromTime); |
||||
107 | $textsMessage = ''; |
||||
108 | if (count($textsChanges) > 0) { |
||||
109 | $textsMessage .= count($textsChanges) == 1 ? 'Text:' : 'Texts:'; |
||||
110 | $textsMessage .= "\n" . implode("\n", $textsChanges); |
||||
111 | } |
||||
112 | |||||
113 | return <<<MSG |
||||
114 | $description [$messageId] |
||||
115 | |||||
116 | $booksMessage |
||||
117 | |||||
118 | $textsMessage |
||||
119 | |||||
120 | MSG; |
||||
121 | } |
||||
122 | |||||
123 | /** |
||||
124 | * @RawSql |
||||
125 | * @param string $fromTime |
||||
126 | */ |
||||
127 | private function getChangedBooksDescriptions($fromTime) { |
||||
128 | $sql = "SELECT CONCAT(b.id, ' / ', br.comment, ' / ', IFNULL(b.title_author, ''), ' — ', b.title, ' / ', b.type) |
||||
129 | FROM `book_revision` br |
||||
130 | LEFT JOIN book b on br.book_id = b.id |
||||
131 | WHERE br.date >= '$fromTime' |
||||
132 | LIMIT 1000"; |
||||
133 | return $this->em->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_COLUMN); |
||||
0 ignored issues
–
show
|
|||||
134 | } |
||||
135 | |||||
136 | /** |
||||
137 | * @RawSql |
||||
138 | * @param string $fromTime |
||||
139 | */ |
||||
140 | private function getChangedTextsDescriptions($fromTime) { |
||||
141 | $sql = "SELECT CONCAT(t.id, ' / ', tr.comment, ' / ', GROUP_CONCAT(p.name SEPARATOR ', '), ' — ', t.title, ' / ', t.type) |
||||
142 | FROM `text_revision` tr |
||||
143 | LEFT JOIN `text` t ON tr.text_id = t.id |
||||
144 | LEFT JOIN text_author ta ON ta.text_id = t.id |
||||
145 | LEFT JOIN person p ON p.id = ta.person_id |
||||
146 | WHERE tr.date >= '$fromTime' |
||||
147 | GROUP BY tr.id |
||||
148 | LIMIT 1000"; |
||||
149 | return $this->em->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_COLUMN); |
||||
0 ignored issues
–
show
The function
Doctrine\DBAL\ForwardCom...lity\Result::fetchAll() has been deprecated: Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
150 | } |
||||
151 | } |
||||
152 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.