@@ -64,42 +64,70 @@ private function isAscii($str) {
6464 }
6565
6666 /**
67- * Checks whether the given path exists in NFC or NFD form and returns
68- * the correct form. If no existing path found, returns the pass as
69- * it was given.
67+ * Checks whether the given path exists in NFC or NFD form after checking
68+ * each form for each path section and returns the correct form.
69+ * If no existing path found, returns the path as it was given.
70+ *
71+ * @param string $fullPath path to check
72+ *
73+ * @return string original or converted path, or null if none of the forms was found
74+ */
75+ private function findPathToUse ($ fullPath ) {
76+ $ sections = explode ('/ ' , $ fullPath );
77+ $ path = '' ;
78+ foreach ($ sections as $ section ) {
79+ $ path .= $ section ;
80+ $ convertedPath = $ this ->findPathToUseLastSection ($ path );
81+ if ($ convertedPath === null ) {
82+ // no point in continuing if the section was not found, use original path
83+ return $ fullPath ;
84+ }
85+ $ path = $ convertedPath . '/ ' ;
86+ }
87+ return rtrim ($ path , '/ ' );
88+ }
89+
90+ /**
91+ * Checks whether the last path section of the given path exists in NFC or NFD form
92+ * and returns the correct form. If no existing path found, returns null.
7093 *
71- * @param string $path path to check
94+ * @param string $fullPath path to check
7295 *
73- * @return string original or converted path
96+ * @return string|null original or converted path, or null if none of the forms was found
7497 */
75- private function findPathToUse ($ path ) {
76- if ($ path === '' || $ this ->isAscii ($ path )) {
77- return $ path ;
78- }
79- $ cachedPath = $ this ->namesCache [$ path ];
98+ private function findPathToUseLastSection ($ fullPath ) {
99+ $ cachedPath = $ this ->namesCache [$ fullPath ];
80100 if ($ cachedPath !== null ) {
81101 return $ cachedPath ;
82102 }
83103
84- $ result = $ this ->storage ->file_exists ($ path );
104+ $ sections = explode ('/ ' , $ fullPath );
105+ $ lastSection = array_pop ($ sections );
106+ $ basePath = ltrim (implode ('/ ' , $ sections ) . '/ ' , '/ ' );
107+
108+ if ($ lastSection === '' || $ this ->isAscii ($ lastSection )) {
109+ return $ fullPath ;
110+ }
111+
112+ $ result = $ this ->storage ->file_exists ($ fullPath );
85113 if ($ result ) {
86- $ this ->namesCache [$ path ] = $ path ;
87- return $ path ;
114+ $ this ->namesCache [$ fullPath ] = $ fullPath ;
115+ return $ fullPath ;
88116 }
89117 // swap encoding
90- if (\Normalizer::isNormalized ($ path , \Normalizer::FORM_C )) {
91- $ otherFormPath = \Normalizer::normalize ($ path , \Normalizer::FORM_D );
118+ if (\Normalizer::isNormalized ($ lastSection , \Normalizer::FORM_C )) {
119+ $ otherFormPath = \Normalizer::normalize ($ lastSection , \Normalizer::FORM_D );
92120 } else {
93- $ otherFormPath = \Normalizer::normalize ($ path , \Normalizer::FORM_C );
121+ $ otherFormPath = \Normalizer::normalize ($ lastSection , \Normalizer::FORM_C );
94122 }
95- if ($ this ->storage ->file_exists ($ otherFormPath )) {
96- $ this ->namesCache [$ path ] = $ otherFormPath ;
97- return $ otherFormPath ;
123+ if ($ this ->storage ->file_exists ($ basePath . $ otherFormPath )) {
124+ $ this ->namesCache [$ fullPath ] = $ basePath . $ otherFormPath ;
125+ return $ basePath . $ otherFormPath ;
98126 }
99127
100128 // return original path, file did not exist at all
101- $ this ->namesCache ->set [$ path ] = self ::NOT_FOUND ;
102- return $ path ;
129+ $ this ->namesCache ->set [$ fullPath ] = self ::NOT_FOUND ;
130+ return null ;
103131 }
104132
105133 /**
0 commit comments