getBaseNameOfURL()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Admin Page Framework
4
 *
5
 * http://admin-page-framework.michaeluno.jp/
6
 * Copyright (c) 2013-2022, Michael Uno; Licensed MIT
7
 *
8
 */
9
10
/**
11
 * Provides utility methods regarding reading file which use WordPress built-in functions and classes.
12
 *
13
 * @since       2.0.0
14
 * @extends     AdminPageFramework_Utility
15
 * @package     AdminPageFramework/Utility
16
 * @internal
17
 */
18
class AdminPageFramework_WPUtility_File extends AdminPageFramework_WPUtility_Hook {
19
20
    /**
21
     * Returns an array of plugin data from the given path.
22
     *
23
     * An alternative to get_plugin_data() as some users change the location of the wp-admin directory.
24
     *
25
     * @since   2.0.0
26
     * @since   3.0.0       Changed the scope to public and become static.
27
     * @since   3.6.2       Supported a text content to be passed to the first parameter.
28
     * @access  public
29
     */
30
    static public function getScriptData( $sPathOrContent, $sType='plugin', $aDefaultHeaderKeys=array() ) {
31
32
        $_aHeaderKeys = $aDefaultHeaderKeys + array(
33
            // storing array key =>    the comment entry header label
34
            'sName'         => 'Name',
35
            'sURI'          => 'URI',
36
            'sScriptName'   => 'Script Name',
37
            'sLibraryName'  => 'Library Name',
38
            'sLibraryURI'   => 'Library URI',
39
            'sPluginName'   => 'Plugin Name',
40
            'sPluginURI'    => 'Plugin URI',
41
            'sThemeName'    => 'Theme Name',
42
            'sThemeURI'     => 'Theme URI',
43
            'sVersion'      => 'Version',
44
            'sDescription'  => 'Description',
45
            'sAuthor'       => 'Author',
46
            'sAuthorURI'    => 'Author URI',
47
            'sTextDomain'   => 'Text Domain',
48
            'sDomainPath'   => 'Domain Path',
49
            'sNetwork'      => 'Network',
50
            // Site Wide Only is deprecated in favour of Network.
51
            '_sitewide'     => 'Site Wide Only',
52
        );
53
54
        $aData = file_exists( $sPathOrContent )
55
            ? get_file_data(
56
                $sPathOrContent,
57
                $_aHeaderKeys,
58
                $sType // context
59
            )
60
            : self::getScriptDataFromContents(
61
                $sPathOrContent,
62
                $sType,
63
                $_aHeaderKeys
64
            );
65
66
        switch ( trim( $sType ) ) {
67
            case 'theme':
68
                $aData['sName'] = $aData['sThemeName'];
69
                $aData['sURI'] = $aData['sThemeURI'];
70
                break;
71
            case 'library':
72
                $aData['sName'] = $aData['sLibraryName'];
73
                $aData['sURI'] = $aData['sLibraryURI'];
74
                break;
75
            case 'script':
76
                $aData['sName'] = $aData['sScriptName'];
77
                break;
78
            case 'plugin':
79
                $aData['sName'] = $aData['sPluginName'];
80
                $aData['sURI'] = $aData['sPluginURI'];
81
                break;
82
            default:
83
                break;
84
        }
85
86
        return $aData;
87
88
    }
89
90
    /**
91
     * Returns an array of plugin data from the given text content.
92
     * @since       3.6.2
93
     * @return      array       The script data
94
     */
95
    static public function getScriptDataFromContents( $sContent, $sType='plugin', $aDefaultHeaderKeys=array() ) {
96
97
        // Make sure we catch CR-only line endings.
98
        $sContent = str_replace( "\r", "\n", $sContent );
99
100
        $_aHeaders      = $aDefaultHeaderKeys;
101
        if ( $sType ) {
102
            $_aExtraHeaders = apply_filters( "extra_{$sType}_headers", array() );
103
            if ( ! empty( $_aExtraHeaders ) ) {
104
                $_aExtraHeaders = array_combine( $_aExtraHeaders, $_aExtraHeaders ); // keys equal values
105
                $_aHeaders      = array_merge( $_aExtraHeaders, ( array ) $aDefaultHeaderKeys );
106
            }
107
        }
108
109
        foreach ( $_aHeaders as $_sHeaderKey => $_sRegex ) {
110
            $_bFound = preg_match( '/^[ \t\/*#@]*' . preg_quote( $_sRegex, '/' ) . ':(.*)$/mi', $sContent, $_aMatch );
111
            $_aHeaders[ $_sHeaderKey ] = $_bFound && $_aMatch[ 1 ]
112
                ? _cleanup_header_comment( $_aMatch[ 1 ] )
113
                : '';
114
        }
115
116
        return $_aHeaders;
117
118
    }
119
120
    /**
121
     * Downloads a file by the given URL.
122
     *
123
     * @remark      The downloaded file should be unlinked(deleted) after it is ued as this function does not do it.
124
     * @since       3.4.2
125
     * @see         download_url() in file.php in core.
126
     */
127
    static public function download( $sURL, $iTimeOut=300 ) {
128
129
        if ( false === filter_var( $sURL, FILTER_VALIDATE_URL ) ) {
130
            return false;
131
        }
132
133
        $_sTmpFileName = self::setTempPath( self::getBaseNameOfURL( $sURL ) );
134
        if ( ! $_sTmpFileName ) {
135
            return false;
136
        }
137
138
        $_aoResponse = wp_safe_remote_get(
139
            $sURL,
140
            array(
141
                'timeout'   => $iTimeOut,
142
                'stream'    => true,
143
                'filename'  => $_sTmpFileName
144
            )
145
        );
146
147
        if ( is_wp_error( $_aoResponse ) ) {
148
            unlink( $_sTmpFileName );
149
            return false;
150
        }
151
152
        if ( 200 != wp_remote_retrieve_response_code( $_aoResponse ) ){
153
            unlink( $_sTmpFileName );
154
            return false;
155
        }
156
157
        $_sContent_md5 = wp_remote_retrieve_header( $_aoResponse, 'content-md5' );
158
        if ( $_sContent_md5 ) {
159
            $_boIsMD5 = verify_file_md5( $_sTmpFileName, $_sContent_md5 );
0 ignored issues
show
Bug introduced by
It seems like $_sContent_md5 can also be of type array; however, parameter $expected_md5 of verify_file_md5() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

159
            $_boIsMD5 = verify_file_md5( $_sTmpFileName, /** @scrutinizer ignore-type */ $_sContent_md5 );
Loading history...
160
            if ( is_wp_error( $_boIsMD5 ) ) {
161
                unlink( $_sTmpFileName );
162
                return false;
163
            }
164
        }
165
166
        return $_sTmpFileName;
167
    }
168
169
    /**
170
     * Sets a temporary file in the system temporary directory and return the file path.
171
     *
172
     * This function respects the file name passed to the parameter.
173
     *
174
     * @since       3.4.2
175
     * @return      string      The set file path.
176
     */
177
    static public function setTempPath( $sFilePath='' ) {
178
179
        $_sDir = get_temp_dir();
180
181
        $sFilePath = basename( $sFilePath );
182
        if ( empty( $sFilePath ) ) {
183
            $sFilePath = time() . '.tmp';
184
        }
185
186
        $sFilePath = $_sDir . wp_unique_filename( $_sDir, $sFilePath );
187
        touch( $sFilePath );
188
        return $sFilePath;
189
190
    }
191
192
    /**
193
     * Returns the base name of a URL.
194
     *
195
     * @since       3.4.2
196
     */
197
    static public function getBaseNameOfURL( $sURL ) {
198
199
        $_sPath         = parse_url( $sURL, PHP_URL_PATH );
200
        $_sFileBaseName = basename( $_sPath );
201
        return $_sFileBaseName;
202
203
    }
204
205
}
206