Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
3 | class URL { |
||
4 | |||
5 | /* replaces the URLs with the {ar*[/nls]} markers */ |
||
6 | 12 | public static function RAWtoAR($page, $nls="") { |
|
7 | 12 | global $ARCurrent, $AR; |
|
8 | 12 | $context = pobject::getContext(); |
|
9 | 12 | $me = $context["arCurrentObject"]; |
|
10 | 12 | if(!$me) { |
|
11 | return $page; |
||
12 | } |
||
13 | |||
14 | 12 | $nls_match = "(/(?:".implode('|', array_keys($AR->nls->list))."))?"; |
|
15 | // FIXME: make the rest of the code also use the $nls_match2 expression |
||
16 | // which doesn't match deel1/ as the nlsid 'de' |
||
17 | 12 | $nls_match2 = "((".implode('|', array_keys($AR->nls->list)).")/)?"; |
|
18 | |||
19 | /* find and replace the current page */ |
||
20 | 12 | $find[] = "%\\Q".$me->make_url($me->path, "\\E{0}(".$nls_match.")\\Q")."\\E(user.edit.page.html|view.html)?%"; |
|
|
|||
21 | 12 | $repl[] = "{arCurrentPage\\1}"; |
|
22 | 12 | $find[] = "%".preg_replace("%^https?://%", "https?\\Q://", $AR->host).$AR->dir->www."loader.php\\E(?:/-".$ARCurrent->session->id."-)?".$nls_match."\\Q".$me->path."\\E(user.edit.page.html|view.html)?%"; |
|
23 | 12 | $repl[] = "{arCurrentPage\\1}"; |
|
24 | 12 | $find[] = "%\\Q".$me->make_local_url($me->path, "\\E{0}(".$nls_match.")\\Q")."\\E(user.edit.page.html|view.html)?%"; |
|
25 | 12 | $repl[] = "{arCurrentPage\\1}"; |
|
26 | // change the site links |
||
27 | 12 | $site = $me->currentsite(); |
|
28 | 12 | if ($site && $site !== '/') { |
|
29 | 6 | $siteURL = $me->make_url($site, ""); |
|
30 | 6 | $rootURL = $me->make_url("/", ""); |
|
31 | |||
32 | /* use the rootURL to rebuild the site URL */ |
||
33 | 6 | $page = preg_replace_callback( |
|
34 | 6 | "%\\Q$rootURL\\E".$nls_match2."\\Q".substr($site, 1)."\\E%", |
|
35 | function ($matches) { |
||
36 | return $matches[2] ? '{arSite/'.$matches[2].'}' : '{arSite}'; |
||
37 | 6 | }, |
|
38 | 6 | $page); |
|
39 | |||
40 | /* |
||
41 | a site has been configured so we can directly place |
||
42 | the nls_match2 after the siteURL |
||
43 | */ |
||
44 | 6 | $page = preg_replace_callback( |
|
45 | 6 | "%\\Q$siteURL\\E".$nls_match2."%", |
|
46 | function ($matches) { |
||
47 | return $matches[2] ? '{arSite/'.$matches[2].'}' : '{arSite}'; |
||
48 | 6 | }, |
|
49 | 6 | $page); |
|
50 | 6 | } |
|
51 | |||
52 | // change hardcoded links and images to use a placeholder for the root |
||
53 | 12 | if ($me->store->get_config("root")) { |
|
54 | $root = $me->store->get_config("root"); |
||
55 | View Code Duplication | if (substr($root, -3) == "/$nls") { |
|
56 | $root = substr($root, 0, -3); |
||
57 | } |
||
58 | $find[] = "%(http[s]?://)?\\Q".$AR->host.$root."\\E".$nls_match."(/)%"; |
||
59 | $repl[] = "{arBase\\2}\\3"; |
||
60 | |||
61 | // This regexp triggers problems if there is no session |
||
62 | // available (either because the user is not logged in, or the |
||
63 | // site in configured with hideSessionFromUrl, so the check is |
||
64 | // added to prevent random /ariadne/loader.php's to be replaced; |
||
65 | if (!empty($ARCurrent->session->id) && strpos($root, "-" . $ARCurrent->session->id . "-") !== false) { |
||
66 | $find[] = "%(http[s]?://)?\\Q".$root."\\E".$nls_match."(?)%"; |
||
67 | $repl[] = "{arBase\\2}\\3"; |
||
68 | } |
||
69 | } |
||
70 | |||
71 | // change hand pasted sources, which may or may not include session id's |
||
72 | 12 | $find[] = "%(https?://)?\\Q".$AR->host.$AR->dir->www."loader.php\\E(/-".$ARCurrent->session->id."-)?(".$nls_match.")?/%"; |
|
73 | 12 | $repl[] = "{arBase\\3}/"; |
|
74 | 12 | if ($ARCurrent->session && $ARCurrent->session->id) { |
|
75 | // check for other session id's: |
||
76 | $find[] = "%/-[^-]{4}-%"; |
||
77 | $repl[] = "{arSession}"; |
||
78 | //$find[] = "%/-".$ARCurrent->session->id."-%"; |
||
79 | //$repl[] = "{arSession}"; |
||
80 | } |
||
81 | |||
82 | 12 | return preg_replace($find, $repl, $page); |
|
83 | } |
||
84 | |||
85 | /* replaces the {ar*[/nls]} markers with valid URLs; if full is false, returns only the <body> content */ |
||
86 | 1 | public static function ARtoRAW($page) { |
|
87 | 1 | global $ARCurrent, $AR; |
|
88 | 1 | $context = pobject::getContext(); |
|
89 | 1 | $me = $context["arCurrentObject"]; |
|
90 | 1 | $find = array(); |
|
91 | 1 | $repl = array(); |
|
92 | |||
93 | 1 | if ($ARCurrent->session && $ARCurrent->session->id) { |
|
94 | $session='/-'.$ARCurrent->session->id.'-'; |
||
95 | } else { |
||
96 | 1 | $session=''; |
|
97 | } |
||
98 | 1 | $site = $me->currentsite($me->path, true); |
|
99 | 1 | $root = $me->store->get_config("root"); |
|
100 | 1 | if (substr($root, -3) == "/$me->nls") { |
|
101 | $root = substr($root, 0, -3); |
||
102 | } |
||
103 | 1 | if ($site && $site !== '/') { |
|
104 | $page = preg_replace_callback( |
||
105 | "%\\{(?:arSite)(?:/([^}]+))?\\}\\Q\\E%", |
||
106 | function ($matches) use ($me, $site) { |
||
107 | return $me->make_url($site, $matches[1]); |
||
108 | }, |
||
109 | $page |
||
110 | ); |
||
111 | |||
112 | $page = preg_replace_callback( |
||
113 | "%\\{(?:arRoot|arBase)(?:/([^}]+))?\\}\\Q".$site."\\E%", |
||
114 | function ($matches) use ($me,$site) { |
||
115 | return $me->make_url($site, $matches[1]); |
||
116 | }, |
||
117 | $page |
||
118 | ); |
||
119 | } |
||
120 | 1 | $find[] = "%\\{arBase(/(?:[^}]+))?\\}%"; |
|
121 | 1 | $repl[] = $AR->host.$root."\\1"; |
|
122 | |||
123 | 1 | $find[] = "%\\{arRoot(/(?:[^}]+))?\\}%"; |
|
124 | 1 | $repl[] = $AR->host.$me->store->get_config("root")."\\1"; |
|
125 | |||
126 | 1 | $page = preg_replace_callback( |
|
127 | 1 | "%\\{arCurrentPage(?:/([^}]+))?\\}%", |
|
128 | 1 | function($matches) use ($me) { |
|
129 | return $me->make_local_url('', $matches[1]); |
||
130 | 1 | }, |
|
131 | $page |
||
132 | 1 | ); |
|
133 | |||
134 | 1 | $find[] = "%\\{arSession\\}%"; |
|
135 | 1 | $repl[] = $session; |
|
136 | |||
137 | 1 | if (class_exists('edit', false) && edit::getEditMode()) { |
|
138 | $find[] = "%ar:editable=([^ ]+)%"; |
||
139 | $repl[] = "contentEditable=\\1"; |
||
140 | } |
||
141 | |||
142 | 1 | $page = preg_replace($find, $repl, $page); |
|
143 | |||
144 | // FIXME: Maybe do not process arCall when ESI is enabled? |
||
145 | 1 | $page = URL::processArCall($page, $full); |
|
146 | |||
147 | 1 | return $page; |
|
148 | } |
||
149 | |||
150 | 1 | protected static function processArCall($page, $full=false) { |
|
211 | } |
||
212 | |||
213 | class pinp_URL { |
||
223 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArray
is initialized the first time when the foreach loop is entered. You can also see that the value of thebar
key is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.