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) { |
|
|
|
|
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
|
|
|
|
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.