@@ -1137,6 +1137,61 @@ public function getUriForPath($path)
1137
1137
return $ this ->getSchemeAndHttpHost ().$ this ->getBaseUrl ().$ path ;
1138
1138
}
1139
1139
1140
+ /**
1141
+ * Returns the path as relative reference from the current Request path.
1142
+ *
1143
+ * Only the URIs path component (no schema, host etc.) is relevant and must be given.
1144
+ * Both paths must be absolute and not contain relative parts.
1145
+ * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
1146
+ * Furthermore, they can be used to reduce the link size in documents.
1147
+ *
1148
+ * Example target paths, given a base path of "/a/b/c/d":
1149
+ * - "/a/b/c/d" -> ""
1150
+ * - "/a/b/c/" -> "./"
1151
+ * - "/a/b/" -> "../"
1152
+ * - "/a/b/c/other" -> "other"
1153
+ * - "/a/x/y" -> "../../x/y"
1154
+ *
1155
+ * @param string $path The target path
1156
+ *
1157
+ * @return string The relative target path
1158
+ */
1159
+ public function getRelativeUriForPath ($ path )
1160
+ {
1161
+ // be sure that we are dealing with an absolute path
1162
+ if (!isset ($ path [0 ]) || '/ ' !== $ path [0 ]) {
1163
+ return $ path ;
1164
+ }
1165
+
1166
+ if ($ path === $ basePath = $ this ->getPathInfo ()) {
1167
+ return '' ;
1168
+ }
1169
+
1170
+ $ sourceDirs = explode ('/ ' , isset ($ basePath [0 ]) && '/ ' === $ basePath [0 ] ? substr ($ basePath , 1 ) : $ basePath );
1171
+ $ targetDirs = explode ('/ ' , isset ($ path [0 ]) && '/ ' === $ path [0 ] ? substr ($ path , 1 ) : $ path );
1172
+ array_pop ($ sourceDirs );
1173
+ $ targetFile = array_pop ($ targetDirs );
1174
+
1175
+ foreach ($ sourceDirs as $ i => $ dir ) {
1176
+ if (isset ($ targetDirs [$ i ]) && $ dir === $ targetDirs [$ i ]) {
1177
+ unset($ sourceDirs [$ i ], $ targetDirs [$ i ]);
1178
+ } else {
1179
+ break ;
1180
+ }
1181
+ }
1182
+
1183
+ $ targetDirs [] = $ targetFile ;
1184
+ $ path = str_repeat ('../ ' , count ($ sourceDirs )).implode ('/ ' , $ targetDirs );
1185
+
1186
+ // A reference to the same base directory or an empty subdirectory must be prefixed with "./".
1187
+ // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
1188
+ // as the first segment of a relative-path reference, as it would be mistaken for a scheme name
1189
+ // (see http://tools.ietf.org/html/rfc3986#section-4.2).
1190
+ return !isset ($ path [0 ]) || '/ ' === $ path [0 ]
1191
+ || false !== ($ colonPos = strpos ($ path , ': ' )) && ($ colonPos < ($ slashPos = strpos ($ path , '/ ' )) || false === $ slashPos )
1192
+ ? "./ $ path " : $ path ;
1193
+ }
1194
+
1140
1195
/**
1141
1196
* Generates the normalized query string for the Request.
1142
1197
*
0 commit comments