Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Version000406Date20200426154317
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 4
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 preSchemaChange
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 changeSchema
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 postSchemaChange
0.00% covered (danger)
0.00%
0 / 105
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2
3declare(strict_types=1);
4
5namespace OCA\Cospend\Migration;
6
7use Closure;
8use OCP\DB\ISchemaWrapper;
9use OCP\Migration\SimpleMigrationStep;
10use OCP\Migration\IOutput;
11use OCP\DB\QueryBuilder\IQueryBuilder;
12use OCP\IDBConnection;
13use OCP\IL10N;
14
15/**
16 * Auto-generated migration step: Please modify to your needs!
17 */
18class Version000406Date20200426154317 extends SimpleMigrationStep {
19
20    /** @var IDBConnection */
21    private $connection;
22    private $trans;
23
24    /**
25     * @param IDBConnection $connection
26     */
27    public function __construct(IDBConnection $connection, IL10N $l10n) {
28        $this->connection = $connection;
29        $this->trans = $l10n;
30    }
31
32    /**
33     * @param IOutput $output
34     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
35     * @param array $options
36     */
37    public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
38    }
39
40    /**
41     * @param IOutput $output
42     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
43     * @param array $options
44     * @return null|ISchemaWrapper
45     */
46    public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
47        /** @var ISchemaWrapper $schema */
48        $schema = $schemaClosure();
49        $table = $schema->getTable('cospend_categories');
50        $table->addColumn('encoded_icon', 'string', [
51            'notnull' => false,
52            'length' => 64,
53            'default' => null
54        ]);
55        return $schema;
56    }
57
58    /**
59     * @param IOutput $output
60     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
61     * @param array $options
62     */
63    public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
64        $qb = $this->connection->getQueryBuilder();
65
66        // first, copy icon -> encoded_icon
67        $categoryIconDict = [];
68        $qb->select('c.id', 'c.icon')
69           ->from('cospend_categories', 'c');
70        $req = $qb->executeQuery();
71
72        while ($row = $req->fetch()) {
73            $categoryIconDict[$row['id']] = $row['icon'];
74        }
75        $req->closeCursor();
76        $qb = $qb->resetQueryParts();
77
78        foreach ($categoryIconDict as $id => $icon) {
79            $qb->update('cospend_categories');
80            $qb->set('encoded_icon', $qb->createNamedParameter(urlencode($icon), IQueryBuilder::PARAM_STR));
81            $qb->where(
82                $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))
83            );
84            $req = $qb->executeStatement();
85            $qb = $qb->resetQueryParts();
86        }
87
88        // then add default categories only if none of them is there already
89        // if there was an encoding problem, they are not there,
90        // if everything went fine when upgrading to v0.4.5, they are there and maybe some of them were deleted
91        $categoryNames = [
92            '-1' => $this->trans->t('Grocery'),
93            '-2' => $this->trans->t('Bar/Party'),
94            '-3' => $this->trans->t('Rent'),
95            '-4' => $this->trans->t('Bill'),
96            '-5' => $this->trans->t('Excursion/Culture'),
97            '-6' => $this->trans->t('Health'),
98            '-10' => $this->trans->t('Shopping'),
99            //'-11' => $this->trans->t('Reimbursement'),
100            '-12' => $this->trans->t('Restaurant'),
101            '-13' => $this->trans->t('Accommodation'),
102            '-14' => $this->trans->t('Transport'),
103            '-15' => $this->trans->t('Sport')
104        ];
105        $categoryNameList = array_values($categoryNames);
106        $categoryEncodedIcons = [
107            '-1'  => urlencode('🛒'),
108            '-2'  => urlencode('🎉'),
109            '-3'  => urlencode('🏠'),
110            '-4'  => urlencode('🌩'),
111            '-5'  => urlencode('🚸'),
112            '-6'  => urlencode('💚'),
113            '-10' => urlencode('🛍'),
114            //'-11' => '💰',
115            '-12' => urlencode('🍴'),
116            '-13' => urlencode('🛌'),
117            '-14' => urlencode('🚌'),
118            '-15' => urlencode('🎾')
119        ];
120        $categoryColors = [
121            '-1'  => '#ffaa00',
122            '-2'  => '#aa55ff',
123            '-3'  => '#da8733',
124            '-4'  => '#4aa6b0',
125            '-5'  => '#0055ff',
126            '-6'  => '#bf090c',
127            '-10' => '#e167d1',
128            //'-11' => '#e1d85a',
129            '-12' => '#d0d5e1',
130            '-13' => '#5de1a3',
131            '-14' => '#6f2ee1',
132            '-15' => '#69e177'
133        ];
134        $ts = (new \DateTime())->getTimestamp();
135
136        // get project ids
137        $projectIdList = [];
138        $qb->select('p.id')
139           ->from('cospend_projects', 'p');
140        $req = $qb->executeQuery();
141
142        while ($row = $req->fetch()) {
143            array_push($projectIdList, $row['id']);
144        }
145        $req->closeCursor();
146        $qb = $qb->resetQueryParts();
147
148        foreach ($projectIdList as $projectId) {
149            // is there at least one default category already?
150            $oneDefaultFound = false;
151            $qb->select('c.name')
152               ->from('cospend_categories', 'c')
153               ->where(
154                   $qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
155               );
156            $req = $qb->executeQuery();
157
158            while ($row = $req->fetch()) {
159                if (in_array($row['name'], $categoryNameList)) {
160                    $oneDefaultFound = true;
161                    break;
162                }
163            }
164            $req->closeCursor();
165            $qb = $qb->resetQueryParts();
166
167            // if there is at least one default category found, do not add default categories
168            if (!$oneDefaultFound) {
169                foreach ($categoryNames as $strId => $name) {
170                    $icon = $categoryEncodedIcons[$strId];
171                    $color = $categoryColors[$strId];
172                    // insert new default category
173                    $qb->insert('cospend_categories')
174                        ->values([
175                            'projectid' => $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR),
176                            'encoded_icon' => $qb->createNamedParameter($icon, IQueryBuilder::PARAM_STR),
177                            'color' => $qb->createNamedParameter($color, IQueryBuilder::PARAM_STR),
178                            'name' => $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR)
179                        ]);
180                    $req = $qb->executeStatement();
181                    $qb = $qb->resetQueryParts();
182                    $insertedCategoryId = $qb->getLastInsertId();
183
184                    // convert category ids in existing bills
185                    $qb->update('cospend_bills')
186                        ->set('categoryid', $qb->createNamedParameter($insertedCategoryId, IQueryBuilder::PARAM_INT))
187                        ->set('lastchanged', $qb->createNamedParameter($ts, IQueryBuilder::PARAM_INT))
188                        ->where(
189                            $qb->expr()->eq('projectid', $qb->createNamedParameter($projectId, IQueryBuilder::PARAM_STR))
190                        )
191                        ->andWhere(
192                            $qb->expr()->eq('categoryid', $qb->createNamedParameter((int) $strId, IQueryBuilder::PARAM_INT))
193                        );
194                    $qb->executeStatement();
195                    $qb = $qb->resetQueryParts();
196                }
197            }
198        }
199    }
200}