]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - vendor/wikimedia/relpath/src/RelPath.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / wikimedia / relpath / src / RelPath.php
diff --git a/vendor/wikimedia/relpath/src/RelPath.php b/vendor/wikimedia/relpath/src/RelPath.php
new file mode 100644 (file)
index 0000000..62b5bbe
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright (c) 2015 Ori Livneh <ori@wikimedia.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @file
+ * @author Ori Livneh <ori@wikimedia.org>
+ */
+
+namespace RelPath;
+
+/**
+ * Split a path into path components.
+ *
+ * @param string $path File path.
+ * @return array Array of path components.
+ */
+function splitPath( $path ) {
+       $fragments = array();
+
+       while ( true ) {
+               $cur = dirname( $path );
+               if ( $cur[0] === DIRECTORY_SEPARATOR ) {
+                       // dirname() on Windows sometimes returns a leading backslash, but other
+                       // times retains the leading forward slash. Slashes other than the leading one
+                       // are returned as-is, and therefore do not need to be touched.
+                       // Furthermore, don't break on *nix where \ is allowed in file/directory names.
+                       $cur[0] = '/';
+               }
+
+               if ( $cur === $path || ( $cur === '.' && basename( $path ) === $path ) ) {
+                       break;
+               }
+
+               $fragment = trim( substr( $path, strlen( $cur ) ), '/' );
+
+               if ( !$fragments ) {
+                       $fragments[] = $fragment;
+               } elseif ( $fragment === '..' && basename( $cur ) !== '..' ) {
+                       $cur = dirname( $cur );
+               } elseif ( $fragment !== '.' ) {
+                       $fragments[] = $fragment;
+               }
+
+               $path = $cur;
+       }
+
+       if ( $path !== '' ) {
+               $fragments[] = trim( $path, '/' );
+       }
+
+       return array_reverse( $fragments );
+}
+
+/**
+ * Return a relative filepath to path either from the current directory or from
+ * an optional start directory. Both paths must be absolute.
+ *
+ * @param string $path File path.
+ * @param string $start Start directory. Optional; if not specified, the current
+ *  working directory will be used.
+ * @return string|bool Relative path, or false if input was invalid.
+ */
+function getRelativePath( $path, $start = null ) {
+       if ( $start === null ) {
+               // @codeCoverageIgnoreStart
+               $start = getcwd();
+       }
+       // @codeCoverageIgnoreEnd
+
+       if ( substr( $path, 0, 1 ) !== '/' || substr( $start, 0, 1 ) !== '/' ) {
+               return false;
+       }
+
+       $pathParts = splitPath( $path );
+       $countPathParts = count( $pathParts );
+
+       $startParts = splitPath( $start );
+       $countStartParts = count( $startParts );
+
+       $commonLength = min( $countPathParts, $countStartParts );
+       for ( $i = 0; $i < $commonLength; $i++ ) {
+               if ( $startParts[$i] !== $pathParts[$i] ) {
+                       break;
+               }
+       }
+
+       $relList = ( $countStartParts > $i )
+               ? array_fill( 0, $countStartParts - $i, '..' )
+               : array();
+
+       $relList = array_merge( $relList, array_slice( $pathParts, $i ) );
+
+       return implode( '/', $relList ) ?: '.';
+}
+
+
+/**
+ * Join path components.
+ *
+ * @param string $base Base path.
+ * @param string $path File path to join to base path.
+ * @return string
+ */
+function joinPath( $base, $path ) {
+       if ( substr( $path, 0, 1 ) === '/' ) {
+               return $path;  // $path is absolute.
+       }
+
+       if ( substr( $base, 0, 1 ) !== '/' ) {
+               return false;  // $base is relative.
+       }
+
+       $pathParts = splitPath( $path );
+       $resultParts = splitPath( $base );
+
+       while ( ( $part = array_shift( $pathParts ) ) !== null ) {
+               switch ( $part ) {
+               case '.':
+                       break;
+               case '..':
+                       if ( count( $resultParts ) > 1 ) {
+                               array_pop( $resultParts );
+                       }
+                       break;
+               default:
+                       $resultParts[] = $part;
+                       break;
+               }
+       }
+
+       return implode( '/', $resultParts );
+}