them / frog_page_metadata

Plug-in for Frog CMS to add metadata to the pages

This URL has Read+Write access

frog_page_metadata / PageMetadataController.php
100644 252 lines (217 sloc) 7.4 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<?php
AutoLoader::addFolder(dirname(__FILE__) . '/models');
AutoLoader::addFolder(dirname(__FILE__) . '/lib');
 
/**
* Simple plugin that adds more metadata to the page view.
*/
class PageMetadataController extends PluginController {
  // Plugin information
  const PLUGIN_ID = "page_metadata";
 
  // Location of the view folder
  const VIEW_FOLDER = "page_metadata/views/";
  const PLUGIN_REL_VIEW_FOLDER = "../../plugins/page_metadata/views/";
  
  // CSS handling for classes and IDs for this plugin
  const CSS_ID_PREFIX = "Page-metadata-";
  const CSS_CLASS_PREFIX = "page-metadata-";
  
  // Singleton instance for observers
  private static $Instance;
 
  /**
* Returns the instance of the controller.
*
* @return the instance of the controller object
*/
  public static function Get_instance() {
    if (!self::$Instance) {
      $class = __CLASS__;
      self::$Instance = new $class();
    }
  
    return self::$Instance;
  }
 
  /**
* Create a new controller instance and apply the sidebar to the backend.
*/
  public function __construct() {
    AuthUser::load();
    if (!(AuthUser::isLoggedIn())) {
        redirect(get_url('login'));
    }
    
    $this->setLayout('backend');
  }
 
  /**
* Catch non-existing controller requests to home.
*/
  public function __call($name, $args) {
    redirect(get_url(''));
  }
 
  /**
* Settings function to delete the metadata table.
*/
  public function settings() {
    $this->display('settings');
  }
  
  public function cleanup() {
    // XXX: because there is no permission check from the backend, it must be done here
    if (!AuthUser::hasPermission('administrator') && !AuthUser::hasPermission('developer')) {
      redirect(get_url());
    }
    
    $table_name = TABLE_PREFIX.PageMetadata::TABLE_NAME;
 
    // Connection
    $pdo = Record::getConnection();
 
    // Clean metadata
    $pdo->exec("DROP TABLE $table_name");
    
    Flash::set('success', __("Table for Page Metadata deleted. Disable the plugin now."));
    redirect(get_url('setting'));
  }
  
  /**
* Returns the template for the view fragments of new metadata that is going to be added.
*/
  public function template() {
    if ( !isset($_POST["keyword"]) || !isset($_POST["value"]) ) {
      header("HTTP/1.0 412 Precondition Failed");
      header("Status: 412 Precondition Failed");
      exit();
    }
 
    $this->setLayout(false);
 
    $this->display('template', array(
      'keyword' => $_POST["keyword"],
      'value' => $_POST["value"],
      /* NOTE: Any unique value is ok for the index used in the form.
The update function only uses the keyword name and ignores
the index. */
      'unique' => time(),
    ));
  }
 
  /**
* Private function that provide the default values for the view.
*
* @return default values
*/
  private function get_default_view_vars() {
    $vars = array();
    
    $vars['plugin_id'] = self::PLUGIN_ID;
    $vars['css_id_prefix'] = self::CSS_ID_PREFIX;
    $vars['css_class_prefix'] = self::CSS_CLASS_PREFIX;
    $vars['plugin_url'] = get_url('plugin/'.self::PLUGIN_ID.'/');
    
    return $vars;
  }
 
  /**
* Overwrite the render function to enforce that some variables are
* available for the whole view artifacts.
* Simplify the view file handling by prefixing the file with the
* plugin directory.
*
* @param view the view file
* @param vars parameter for the views
* @return the view
*/
  /*@overwrite('render')*/
  public function render($view, $vars=array()) {
    $vars = array_merge($this->get_default_view_vars(), $vars);
 
    /* We only render views for this plugin. So add the prefix of the view folder to every view file. */
    return parent::render(self::VIEW_FOLDER.$view, $vars);
  }
 
  /**
* View factory for the controller and the view.
*
* @param view the filename without the postfix
* @param vars the template vars
* @return a view object
*/
  public function create_view($view, $vars=array()) {
    $vars = array_merge($this->get_default_view_vars(), $vars);
      
    return new View(self::PLUGIN_REL_VIEW_FOLDER.$view, $vars);
  }
 
  /**
* Adds a new tab with the metadata.
*
* @param the current page
*/
  public static function Callback_view_page_edit_tabs($page) {
    $metadata = array();
    
    // Only for existing pages there can be metadata
    if (isset($page->id) && !empty($page->id)) {
      $metadata = PageMetadata::FindAllByPage($page);
    }
    
    // Display the metadata form with metadata (if any).
    self::Get_instance()->create_view('metadata', array(
      'metadata' => $metadata,
    ))->display();
  }
  
  /**
* Displays the popup dialog for adding new metadata.
*/
  public static function Callback_view_page_edit_popup() {
    self::Get_instance()->create_view('new_popup')->display();
  }
  
  /**
* Apply additional metadata to page object before displayed.
* NOTE: this function manipulates the page object.
*
* @param page the page object
*/
  public static function Callback_page_found($page) {
    // PHP is a dynamic language, create new attribute
    $plugin_id = self::PLUGIN_ID;
    // Apply metadata as simple key value array
    $page->$plugin_id = PageMetadata::FindAllByPageAsArray($page);
  }
  
  /**
* Delets all metadata from a deleted page.
*
* @param page the page object
*/
  public static function Callback_page_delete($page) {
    PageMetadata::DeleteAllByPage($page);
  }
  
  /**
* Updates the page metadata. In contrast to the core, the metadata is not removed by the controller directly
* e.g. via an AJAX call. The problem is that newly generated pages do not have an ID and therefore they can not
* be created nor deleted. So the semantic is that keywords with empty values get removed.
*
* @param the current page
*/
  public static function Callback_page_page_updated($page) {
    // If there is no metadata submited at all, just delete (possible) existing ones for this page.
    // There could be invisible metadata (from other plug-ins). Thanks to: Andy
    if (!isset($_POST[self::PLUGIN_ID])) {
      PageMetadata::DeleteAllByPage($page);
      return;
    }
    
    // Get all posted metadata
    foreach ($_POST[self::PLUGIN_ID] as $metadata) {
      $value = trim($metadata["value"]);
      $keyword = $metadata["name"];
      // Visible is more like a 'hack' to allow other plugins to style the metadata
      // in their own way.
      $visible = isset($metadata["visible"]) ? $metadata["visible"] : 1;
      
      // If the metadata is not existing, create it.
      $is_in_db = true;
      if (!$obj = PageMetadata::FindOneByPageAndKeyword($page, $keyword)) {
        $is_in_db = false;
        // New value object
        $obj = new PageMetadata(array(
          "page_id" => $page->id,
          "keyword" => $keyword,
          "visible" => $visible,
        ));
      }
 
      // Skip or delete empty values.
      if (empty($value)) {
          // Delete metadata if value is empty
          if ($is_in_db) {
            $obj->delete();
          }
          else {
            continue;
          }
        }
        else {
          // Update data and save.
          $obj->value = $value;
          $obj->visible = $visible;
          $obj->save();
        }
    }
  }
}
?>