Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 70
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Utils
0.00% covered (danger)
0.00%
0 / 70
0.00% covered (danger)
0.00%
0 / 3
132
0.00% covered (danger)
0.00%
0 / 1
 encodeTitle
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
20
 decodeURL
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
30
 needsShortUrl
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Functions used for decoding/encoding ids in ShortUrl Extension
4 *
5 * @file
6 * @ingroup Extensions
7 * @author Yuvi Panda, http://yuvi.in
8 * @copyright © 2011 Yuvaraj Pandian (yuvipanda@yuvi.in)
9 * @license BSD-3-Clause
10 */
11
12namespace MediaWiki\Extension\ShortUrl;
13
14use MediaWiki\MediaWikiServices;
15use MediaWiki\Title\Title;
16
17/**
18 * Utility functions for encoding and decoding short URLs
19 */
20class Utils {
21
22    /**
23     * @param Title $title
24     * @return string|bool false if read-only mode
25     */
26    public static function encodeTitle( Title $title ) {
27        global $wgShortUrlReadOnly;
28
29        if ( $wgShortUrlReadOnly ) {
30            // Not creating any new ids
31            return false;
32        }
33
34        $fname = __METHOD__;
35        $services = MediaWikiServices::getInstance();
36        $cache = $services->getMainWANObjectCache();
37        $connectionProvider = $services->getConnectionProvider();
38
39        return $cache->getWithSetCallback(
40            $cache->makeKey( 'shorturls-title', md5( $title->getPrefixedText() ) ),
41            $cache::TTL_MONTH,
42            static function () use ( $title, $fname, $connectionProvider ) {
43                $id = $connectionProvider->getReplicaDatabase()->newSelectQueryBuilder()
44                    ->select( 'su_id' )
45                    ->from( 'shorturls' )
46                    ->where( [
47                        'su_namespace' => $title->getNamespace(),
48                        'su_title' => $title->getDBkey()
49                    ] )
50                    ->caller( $fname )
51                    ->fetchField();
52
53                // Automatically create an ID for this title if missing...
54                if ( !$id ) {
55                    $dbw = $connectionProvider->getPrimaryDatabase();
56                    $dbw->newInsertQueryBuilder()
57                        ->insertInto( 'shorturls' )
58                        ->ignore()
59                        ->row( [
60                            'su_namespace' => $title->getNamespace(),
61                            'su_title' => $title->getDBkey()
62                        ] )
63                        ->caller( $fname )
64                        ->execute();
65
66                    if ( $dbw->affectedRows() ) {
67                        $id = $dbw->insertId();
68                    } else {
69                        // Raced out; get the winning ID
70                        $id = $dbw->newSelectQueryBuilder()
71                            ->select( 'su_id' )
72                            ->from( 'shorturls' )
73                            ->where( [
74                                'su_namespace' => $title->getNamespace(),
75                                'su_title' => $title->getDBkey()
76                            ] )
77                            ->caller( $fname )
78                            ->lockInShareMode()
79                            ->fetchField();
80                    }
81                }
82
83                return base_convert( $id, 10, 36 );
84            }
85        );
86    }
87
88    /**
89     * @param string|null $urlFragment
90     * @return Title|bool
91     */
92    public static function decodeURL( $urlFragment ) {
93        if ( $urlFragment === null
94            || !preg_match( '/^[0-9a-z]+$/i', $urlFragment )
95        ) {
96            return false;
97        }
98
99        $id = intval( base_convert( $urlFragment, 36, 10 ) );
100
101        $fname = __METHOD__;
102        $services = MediaWikiServices::getInstance();
103        $cache = $services->getMainWANObjectCache();
104        $connectionProvider = $services->getConnectionProvider();
105        $row = $cache->getWithSetCallback(
106            $cache->makeKey( 'shorturls-id', $id ),
107            $cache::TTL_MONTH,
108            static function () use ( $id, $fname, $connectionProvider ) {
109                $dbr = $connectionProvider->getReplicaDatabase();
110                $row = $dbr->newSelectQueryBuilder()
111                    ->select( [ 'su_namespace', 'su_title' ] )
112                    ->from( 'shorturls' )
113                    ->where( [ 'su_id' => $id ] )
114                    ->caller( $fname )
115                    ->fetchRow();
116
117                return $row ? (array)$row : false;
118            }
119        );
120
121        return $row ? Title::makeTitle( $row['su_namespace'], $row['su_title'] ) : false;
122    }
123
124    /**
125     * @param Title $title
126     * @return bool true if a short URL needs to be displayed
127     */
128    public static function needsShortUrl( $title ) {
129        return $title->exists() && !$title->isMainPage();
130    }
131}