This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | class MenuCache extends DataExtension |
||
4 | { |
||
5 | /** |
||
6 | * fields are typicall header, menu, footer |
||
7 | */ |
||
8 | |||
9 | private static $db = array( |
||
10 | "CachedSection0" => "HTMLText", |
||
11 | "CachedSection1" => "HTMLText", |
||
12 | "CachedSection2" => "HTMLText", |
||
13 | "CachedSection3" => "HTMLText", |
||
14 | "CachedSection4" => "HTMLText" |
||
15 | ); |
||
16 | |||
17 | private static $fields = array( |
||
18 | 0 => "Header", |
||
19 | 1 => "Menu", |
||
20 | 2 => "Footer", |
||
21 | 3 => "LayoutSection", |
||
22 | 4 => "other", |
||
23 | ); |
||
24 | |||
25 | /* sets the cache number used for getting the "$Layout" of the individual page */ |
||
26 | private static $layout_field = 3; |
||
27 | |||
28 | private static $tables_to_clear = array("SiteTree", "SiteTree_Live", "SiteTree_versions"); |
||
29 | |||
30 | public static function field_maker($fieldNumber) |
||
31 | { |
||
32 | return "CachedSection".$fieldNumber; |
||
33 | } |
||
34 | |||
35 | public static function fields_exists($number) |
||
36 | { |
||
37 | return (isset(self::$fields[$number])); |
||
38 | } |
||
39 | |||
40 | public function updateCMSFields(FieldList $fields) |
||
41 | { |
||
42 | $fields->addFieldToTab("Root.Caching", new CheckboxField("DoNotCacheMenu", "Do Not Cache Menu")); |
||
43 | $fields->addFieldToTab("Root.Caching", new LiteralField("ClearCache", "<a href=\"".$this->owner->Link("clearallfieldcaches")."\">clear cache (do this at the end of all edit sessions)</a>")); |
||
44 | return $fields; |
||
45 | } |
||
46 | |||
47 | //-------------------- menu cache ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ |
||
48 | |||
49 | public function clearfieldcache($showoutput = false) |
||
50 | { |
||
51 | $fieldsToClear = array(); |
||
52 | $fieldsForEach = Config::inst()->get("MenuCache", "fields"); |
||
53 | foreach ($fieldsForEach as $key => $field) { |
||
54 | $fieldName = self::field_maker($key); |
||
55 | $fieldsToClear[] = "\"".$fieldName."\" = ''"; |
||
56 | } |
||
57 | if (count($fieldsToClear)) { |
||
58 | $tablesForEach = Config::inst()->get("MenuCache", "tables_to_clear"); |
||
59 | foreach ($tablesForEach as $table) { |
||
0 ignored issues
–
show
|
|||
60 | $msg = ''; |
||
61 | $sql = "UPDATE \"".$table."\" SET ".implode(", ", $fieldsToClear); |
||
62 | if (Controller::curr()->getRequest()->param("ID") == "days" && $days = intval(Controller::curr()->getRequest()->param("OtherID"))) { |
||
63 | $sql .= ' WHERE \"LastEdited\" > ( NOW() - INTERVAL '.$days.' DAY )'; |
||
64 | $msg .= ', created before the last '.$days.' days'; |
||
65 | } elseif (Controller::curr()->getRequest()->param("ID") == "thispage") { |
||
66 | $sql .= " WHERE \"".$table."\".\"ID\" = ".$this->owner->ID; |
||
67 | $msg .= ', for page with ID = '.$this->owner->ID; |
||
68 | } |
||
69 | if ($showoutput) { |
||
70 | DB::alteration_message("Deleting cached data from $table, ".$msg); |
||
71 | debug::show($sql); |
||
72 | } |
||
73 | DB::query($sql); |
||
74 | } |
||
75 | } |
||
76 | return array(); |
||
77 | } |
||
78 | |||
79 | //add this function to your page class if needed |
||
80 | public function onBeforeWrite() |
||
81 | { |
||
82 | //$this->clearfieldcache(); // technically this should be done, but it puts a lot of strain on saving so instead we encourage people to use ?flush=1 |
||
83 | parent::onBeforeWrite(); |
||
84 | } |
||
85 | } |
||
86 | |||
87 | class MenuCache_Controller extends Extension |
||
88 | { |
||
89 | private static $allowed_actions = array("showcachedfield","clearfieldcache","showuncachedfield", "clearallfieldcaches"); |
||
90 | |||
91 | protected function getHtml($fieldNumber) |
||
92 | { |
||
93 | $layoutField = Config::inst()->get("MenuCache", "layout_field"); |
||
94 | if ($layoutField == $fieldNumber) { |
||
95 | $className = $this->owner->ClassName; |
||
96 | if ("Page" == $className) { |
||
97 | $className = "PageCached"; |
||
98 | } |
||
99 | return $this->owner->renderWith(array($className, "PageCached")); |
||
100 | } else { |
||
101 | return $this->owner->renderWith('UsedToCreateCache'.$fieldNumber); |
||
102 | } |
||
103 | } |
||
104 | |||
105 | public function CachedField($fieldNumber) |
||
106 | { |
||
107 | $fieldName = MenuCache::field_maker($fieldNumber); |
||
108 | if (isset($_REQUEST["flush"])) { |
||
109 | $this->owner->clearfieldcache(); |
||
110 | } |
||
111 | if (!(MenuCache::fields_exists($fieldNumber))) { |
||
112 | user_error("$fieldName is not a field that can be cached", E_USER_ERROR); |
||
113 | } else { |
||
114 | if (!$this->owner->$fieldName || $this->owner->DoNotCacheMenu) { |
||
115 | $fieldID = $fieldNumber; |
||
116 | $content = $this->getHtml($fieldNumber); |
||
117 | $sql = "Update \"SiteTree_Live\" Set \"".$fieldName."\" = '".$this->compressAndPrepareHTML($content)."' WHERE \"ID\" = ".$this->owner->ID." LIMIT 1"; |
||
118 | DB::query($sql); |
||
119 | return $content; |
||
120 | } else { |
||
121 | return $this->owner->$fieldName; |
||
122 | } |
||
123 | } |
||
124 | } |
||
125 | |||
126 | |||
127 | private function compressAndPrepareHTML($html) |
||
128 | { |
||
129 | $pat[0] = "/^\s+/"; |
||
130 | $pat[1] = "/\s{2,}/"; |
||
131 | $pat[2] = "/\s+\$/"; |
||
132 | $rep[0] = ""; |
||
133 | $rep[1] = " "; |
||
134 | $rep[2] = ""; |
||
135 | $html = preg_replace($pat, $rep, $html); |
||
136 | $html = trim($html); |
||
137 | return addslashes($html); |
||
138 | } |
||
139 | |||
140 | |||
141 | |||
142 | public function showcachedfield($httpRequest = null) |
||
143 | { |
||
144 | $fieldNumber = $httpRequest->param("ID"); |
||
145 | return $this->getHtml($fieldNumber); |
||
146 | } |
||
147 | |||
148 | public function showuncachedfield($httpRequest = null) |
||
149 | { |
||
150 | $this->owner->clearfieldcache(); |
||
151 | return $this->showcachedfield($httpRequest); |
||
152 | } |
||
153 | |||
154 | public function clearallfieldcaches($httpRequest = null) |
||
155 | { |
||
156 | $this->owner->clearfieldcache(true); |
||
157 | return 'fields have been cleared, <a href="/?flush=all">click to continue...</a>'; |
||
158 | } |
||
159 | } |
||
160 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.