Web · Wiki · Activities · Blog · Lists · Chat · Meeting · Bugs · Git · Translate · Archive · People · Donate
1
<?php
2
/* ***** BEGIN LICENSE BLOCK *****
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
 *
5
 * The contents of this file are subject to the Mozilla Public License Version
6
 * 1.1 (the "License"); you may not use this file except in compliance with
7
 * the License. You may obtain a copy of the License at
8
 * http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the
13
 * License.
14
 *
15
 * The Original Code is addons.mozilla.org site.
16
 *
17
 * The Initial Developer of the Original Code is
18
 * The Mozilla Foundation.
19
 * Portions created by the Initial Developer are Copyright (C) 2006
20
 * the Initial Developer. All Rights Reserved.
21
 *
22
 * Contributor(s):
23
 *   Andrei Hajdukewycz <sancus@off.net> (Original Author)
24
 *   Justin Scott <fligtar@gmail.com>
25
 *   Mike Morgan <morgamic@mozilla.com>
26
 *   Frederic Wenzel <fwenzel@mozilla.com>
27
 *
28
 * Alternatively, the contents of this file may be used under the terms of
29
 * either the GNU General Public License Version 2 or later (the "GPL"), or
30
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31
 * in which case the provisions of the GPL or the LGPL are applicable instead
32
 * of those above. If you wish to allow use of your version of this file only
33
 * under the terms of either the GPL or the LGPL, and not to allow others to
34
 * use your version of this file under the terms of the MPL, indicate your
35
 * decision by deleting the provisions above and replace them with the notice
36
 * and other provisions required by the GPL or the LGPL. If you do not delete
37
 * the provisions above, a recipient may use your version of this file under
38
 * the terms of any one of the MPL, the GPL or the LGPL.
39
 *
40
 * ***** END LICENSE BLOCK ***** */
41
42
class Version extends AppModel
43
{
44
    var $name = 'Version';
45
    var $belongsTo_full = array('Addon' =>
46
                                array('className' => 'Addon'),
47
                                'License' =>
48
                                array('className'  => 'License',
49
                                      'conditions' => '',
50
                                      'order'      => '',
51
                                      'foreignKey' => 'license_id'
52
                                )
53
                          );
54
55
    var $hasMany = array('Review' =>
56
                         array('className'   => 'Review',
57
                               'conditions'  => '',
58
                               'order'       => '',
59
                               'limit'       => '',
60
                               'foreignKey'  => 'version_id',
61
                               'dependent'   => true,
62
                               'exclusive'   => false,
63
                               'finderSql'   => ''
64
                         ),
65
                       'File' =>
66
                         array('className'   => 'File',
67
                               'conditions'  => '',
68
                               'order'       => '',
69
                               'limit'       => '',
70
                               'foreignKey'  => 'version_id',
71
                               'dependent'   => true,
72
                               'exclusive'   => false,
73
                               'finderSql'   => ''
74
                         )
75
                  );
76
    var $hasAndBelongsToMany = array('Application' =>
77
                                      array('className'  => 'Application',
78
                                            'joinTable'  => 'applications_versions',
79
                                            'foreignKey' => 'version_id',
80
                                            'associationForeignKey'=> 'application_id',
81
                                            'conditions' => '',
82
                                            'order'      => '',
83
                                            'limit'      => '',
84
                                            'unique'     => false,
85
                                            'finderSql'  => '',
86
                                            'deleteQuery'=> ''
87
                                      )
88
                               );
89
90
    var $translated_fields = array(
91
                'releasenotes'
92
            );    
93
94
    var $validate = array(
95
                          'addon_id' => VALID_NUMBER,
96
                          'version' => VALID_NOT_EMPTY
97
                    );
98
99
    /**
100
     * Return the id or ids of valid versions by add-on id.
101
     *
102
     * @param mixed $id
103
     * @param array $status non-empty array
104
     * @return aray|boolean array of valid version_ids on success or false on failure
105
     */
106
    function getVersionIdsByAddonId($id, $status = array(STATUS_PUBLIC)) {
107
108
        // Implode our status array
109
        $status_sql = implode(',',$status);
110
111
        $id_sql = is_array($id) ? implode(',',$id) : $id;
112
113
        $sql = "
114
            SELECT DISTINCT
115
                Version.id
116
            FROM
117
                versions AS Version
118
            INNER JOIN
119
                files AS File ON File.status IN ({$status_sql}) AND File.version_id = Version.id 
120
            WHERE
121
                Version.addon_id IN ({$id_sql})
122
            ORDER BY
123
                Version.created DESC
124
        ";
125
126
        return $this->query($sql);
127
    }
128
129
    /**
130
     * Return the latest version id by add-on id.
131
     *
132
     * @param int $id
133
     * @param array $status non-empty array
134
     * @return int $id of the latest version or 0
135
     */
136
    function getVersionByAddonId($id, $status = array(STATUS_PUBLIC), $app_ver = null) {
137
        if (!is_array($status)) $status = array($status);
138
        $status_sql = implode(',',$status);
139
140
        if (!isset($app_ver) || $app_ver == 'any')
141
            $app_ver = parse_sp();
142
143
        $sql = "
144
            SELECT 
145
                Version.id
146
            FROM
147
                versions AS Version
148
            INNER JOIN
149
                files AS File ON File.status IN ({$status_sql}) AND File.version_id = Version.id 
150
            INNER JOIN
151
                applications_versions A ON A.version_id = Version.id
152
            INNER JOIN
153
                appversions as B ON B.id = A.min
154
            INNER JOIN
155
                appversions as C ON C.id = A.max
156
            WHERE
157
                Version.addon_id = {$id}
158
            ORDER BY
159
                Version.id + IF({$app_ver} >= CAST(B.version AS DECIMAL(3,3)) AND {$app_ver} <= CAST(C.version AS DECIMAL(3,3)), 1000000, 0) DESC
160
            LIMIT 1
161
        ";
162
163
        $buf = $this->query($sql);
164
165
        if (!empty($buf[0]['Version']['id'])) {
166
            return $buf[0]['Version']['id'];
167
        }
168
169
        return 0;
170
    }
171
172
    function getVersionByAddonIdAndVersion($id, $version, $status = array(STATUS_PUBLIC), $app_ver = null) {
173
        if (!is_array($status)) $status = array($status);
174
        $status_sql = implode(',',$status);
175
176
        if (!isset($app_ver) || $app_ver == 'any')
177
            $app_ver = parse_sp();
178
        if (!isset($version) || $version == '')
179
            $version = '0';
180
181
        $sql = "
182
            SELECT 
183
                Version.id
184
            FROM
185
                versions AS Version
186
            INNER JOIN
187
                files AS File ON File.status IN ({$status_sql}) AND File.version_id = Version.id 
188
            INNER JOIN
189
                applications_versions A ON A.version_id = Version.id
190
            INNER JOIN
191
                appversions as B ON B.id = A.min
192
            INNER JOIN
193
                appversions as C ON C.id = A.max
194
            WHERE
195
                Version.addon_id = {$id} AND ({$version} = 0 OR Version.version = {$version})
196
            ORDER BY
197
                Version.id + IF({$app_ver} >= CAST(B.version AS DECIMAL(3,3)) AND {$app_ver} <= CAST(C.version AS DECIMAL(3,3)), 1000000, 0) DESC
198
            LIMIT 1
199
        ";
200
201
        $buf = $this->query($sql);
202
203
        if (!empty($buf[0]['Version']['id'])) {
204
            return $buf[0]['Version']['id'];
205
        }
206
207
        return 0;
208
    }
209
    
210
    /**
211
     * Get the apps compatible with a given addon version
212
     */
213
    function getCompatibleApps($id) {
214
        global $app_shortnames;
215
        
216
        $supported_app_ids = implode(',',array_values($app_shortnames));
217
        $sql = "
218
            SELECT
219
                Application.application_id,
220
                Min_Version.version,
221
                Max_Version.version
222
            FROM
223
                applications_versions AS Application
224
            INNER JOIN
225
                appversions AS Min_Version ON (Min_Version.id = Application.`min`)
226
            INNER JOIN
227
                appversions AS Max_Version ON (Max_Version.id = Application.`max`)
228
            WHERE
229
                Application.version_id = '{$id}'
230
            AND
231
                Application.application_id IN ({$supported_app_ids})
232
            ORDER BY
233
                (Application.application_id = '".APP_ID."') DESC,
234
                FIELD(Application.application_id,{$supported_app_ids})
235
        ";
236
        return $this->query($sql, true);
237
    }
238
    
239
    /**
240
     * Gets the apps compatible with a given add-on version in the form of ids
241
     * instead of the actual version numbers and organizes them by application_id
242
     */
243
    function getCompatibleAppIds($version_id) {
244
        $apps = $this->query("
245
            SELECT
246
                `applications_versions`.`application_id`,
247
                `min`.`id`,
248
                `max`.`id`
249
            FROM
250
                `applications_versions`
251
            INNER JOIN
252
                `appversions` AS `min` ON `applications_versions`.`min`=`min`.`id`
253
            INNER JOIN
254
                `appversions` AS `max` ON `applications_versions`.`max`=`max`.`id`
255
            WHERE
256
                `applications_versions`.`version_id`='{$version_id}'
257
            ", true);
258
        
259
        $list = array();
260
        
261
        if (!empty($apps)) {
262
            foreach ($apps as $app) {
263
                $list[$app['applications_versions']['application_id']] = array(
264
                    'min' => $app['min']['id'],
265
                    'max' => $app['max']['id']
266
                );
267
            }
268
        }
269
        
270
        return $list;
271
    }
272
    
273
    /**
274
     * Adds a compatible application to the specified version
275
     * @param int $version_id version id
276
     * @param int $application_id application id
277
     * @param int $minVersion appversion id (not the actual version string)
278
     * @param int $maxVersion appversion id (not the actual version string)
279
     */
280
    function addCompatibleApp($version_id, $application_id, $minVersion, $maxVersion) {
281
        $this->execute("
282
                INSERT INTO
283
                    applications_versions (
284
                        application_id,
285
                        version_id,
286
                        min,
287
                        max
288
                    )
289
                    VALUES (
290
                        {$application_id},
291
                        {$version_id},
292
                        {$minVersion},
293
                        {$maxVersion}
294
                    )
295
            ");
296
    }
297
    
298
    /**
299
     * Removes a compatible application from the specified version
300
     * @param int $version_id version id
301
     * @param int $application_id application id
302
     */
303
    function removeCompatibleApp($version_id, $application_id) {
304
        $this->execute("
305
                DELETE FROM
306
                    applications_versions
307
                WHERE
308
                    version_id={$version_id} AND
309
                    application_id={$application_id}
310
            ");
311
    }
312
    
313
    /**
314
     * Updates compatiblity for the specified app and version
315
     * @param int $version_id version id
316
     * @param int $application_id application id
317
     * @param int $minVersion appversion id (not the actual version string)
318
     * @param int $maxVersion appversion id (not the actual version string)
319
     */
320
    function updateCompatibility($version_id, $application_id, $minVersion, $maxVersion) {
321
        $this->execute("
322
                UPDATE
323
                    applications_versions
324
                SET
325
                    min={$minVersion},
326
                    max={$maxVersion}
327
                WHERE
328
                    version_id={$version_id} AND
329
                    application_id={$application_id}
330
            ");
331
    }
332
    
333
    /**
334
     * Returns an array of file ids associated with the given version.
335
     * @param int $version_id version id
336
     * @return array
337
     */
338
    function getFileIDs($version_id) {
339
        $files = $this->query("SELECT id FROM files WHERE version_id={$version_id}");
340
        $file_ids = array();
341
        
342
        if (!empty($files)) {
343
            foreach ($files as $file) {
344
                $file_ids[] = $file['files']['id'];
345
            }
346
        }
347
        
348
        return $file_ids;
349
    }
350
351
    function getReleaseNotesLocales($version_id) {
352
        $sql = "   
353
            SELECT 
354
                Translations.locale,
355
                Translations.localized_string
356
            FROM
357
                versions AS Version
358
            INNER JOIN
359
                translations AS Translations ON Translations.id = Version.releasenotes
360
            WHERE
361
                Version.id = {$version_id}
362
        ";
363
364
        $out = array();
365
366
        foreach ($this->query($sql) as $i)
367
            $out[$i['Translations']['locale']] = $i['Translations']['localized_string'];
368
369
        return $out;
370
    }
371
}
372
?>