/[drupal]/contributions/modules/mysite/API.php
ViewVC logotype

Contents of /contributions/modules/mysite/API.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.23 - (show annotations) (download) (as text)
Sun Apr 6 23:08:25 2008 UTC (19 months, 2 weeks ago) by agentken
Branch: MAIN
CVS Tags: DRUPAL-5--3-3, DRUPAL-5--3-2, DRUPAL-5--3-1, DRUPAL-5--3-0, DRUPAL-5--3-0rc2, HEAD
Changes since 1.22: +12 -31 lines
File MIME type: text/x-php
  -- Finishes cleanup up of API and code style.
  -- Creates 5.x.3rc2
1 <?php
2 // $Id: API.php,v 1.22 2008/04/01 00:55:56 agentken Exp $
3
4
5 /**
6 * @defgroup mysite_hooks MySite Hooks
7 * Internal module hooks used by MySite includes.
8 *
9 * These hooks are called by invoking:
10 * @code mysite_{$type}_{$name}_hook() @endcode
11 * This method is used to avoid conflict with Drupal's core hooks and to ensure that only activated
12 * include files are loaded and executed by the system.
13 *
14 * The common method for calling a MySite hook is to use:
15 * @code module_invoke('mysite_{$type}', {$name}. '_hook', $args) @endcode
16 *
17 * MySite contributors and plugin authors do not need to worry about this syntax unless they need
18 * to invoke functions from other MySite includes.
19 *
20 * - NOTE: It is understood that this is a non-standard implementation of the Drupal hook() system. This code
21 * may be re-factored in later releases.
22 */
23
24 /**
25 * @defgroup mysite_plugins MySite Plugins
26 * Files which use the MySite API to add features and functionality.
27 *
28 * MySite uses four types of plugins:
29 * - 'formats' control the display of content on a page.
30 * - 'layouts' control the position of content on a page.
31 * - 'styles' affect the design of content on a page.
32 * - 'types' define the content on a page.
33 */
34
35 /**
36 * @file
37 * Documentation file for MySite's internal hooks.
38 *
39 * @ingroup mysite
40 */
41
42 /**
43 * Basic definition of the content type.
44 *
45 * This hook is used by MySite Type plugins to define the available content types.
46 *
47 * This hook is invoked by the following functions:
48 * - mysite_menu()
49 * - mysite_configure_form()
50 * - mysite_content_form()
51 * - mysite_content_menu()
52 *
53 * The function is almost always wrapped inside an IF statement, since MySite plugins
54 * require that their "parent" modules be active.
55 *
56 * Some of these settings can be altered through the UI, so the $basic_settings routine
57 * is important.
58 *
59 * @param $get_options
60 * A boolean flag indicating whether to append content selection options to the $type array. Default is TRUE.
61 * NOTE: Leaving this value blank will invoke mysite_type_hook_options() which can be resource intensive.
62 * @return
63 * An array of data that defines this content type. The data takes the form:
64 * - 'name': String. The display name of the include type. Required.
65 * - 'description': String. The include description to show to the administrator. Required.
66 * - 'include': String. The filename of the include (without extension). Required.
67 * - 'prefix': String. A text string to prepend to content item names. Optional.
68 * - 'suffix': String. A text string to append to content item names. Optional.
69 * - 'category': String. The plugin category used for sorting content types. Required. Possible values are:
70 * - -- "Aggregation": Content having to do with feed aggregation.
71 * - -- "Content": Generic value. Default.
72 * - -- "MySite": Content native to the MySite module.
73 * - -- "Usability": Items related to design, themes, or other UI areas.
74 * - 'weight': Numeric. The sort order of an include within a category list. Required.
75 * - 'form': Boolean. A flag that indicates whether the include uses mysite_type_hook_form(). Required.
76 * - 'label': String. The content link to show to users. Required.
77 * - 'help': String. Help text to show to users that describes this content. Required.
78 * - 'search': Boolean. A flag indicating that this content can be searched using mysite_type_hook_search(). Required.
79 * - 'admin': Boolean. A flag indicating that this content is only shown on MySite configuration pages. Required if TRUE.
80 * The order of the array does not matter.
81 *
82 * @ingroup mysite_hooks
83 */
84 function mysite_type_hook($get_options = TRUE) {
85 if (module_exists('node')) {
86 $type = array(
87 'name' => t('Hook'),
88 'description' => t('<b>Hook</b>: Definition for the MySite configuration page.'),
89 'include' => 'hook',
90 'prefix' => t(''),
91 'suffix' => t(''),
92 'category' => t('Content'),
93 'weight' => 0,
94 'form' => FALSE,
95 'label' => t('Add Hook'),
96 'help' => t('User help to display on Add Content pages.'),
97 'search' => TRUE,
98 'admin' => FALSE
99 );
100 $basic_settings = variable_get('mysite_basic_type_settings', array());
101 $type = array_merge($type, $basic_settings);
102 if ($get_options) {
103 $type['options'] = mysite_type_hook_options();
104 }
105 return $type;
106 }
107 }
108
109 /**
110 * Checks to see if this include can be enabled. Sets a message to the administrator if FALSE.
111 *
112 * This check is generally a permissions check, but can also check mysite_type_hook_settings() to ensure that
113 * an include has been configured. See mysite_type_term_active() for an example.
114 *
115 * Invoked by mysite_configure_form().
116 *
117 * @param $type
118 * The content type of this include. Passed by mysite_configure_form().
119 * @return
120 * array($type => TRUE, 'message' => t('A String'))
121 * An array where $type is the type string, set to a boolean value indicating that the include can be used.
122 * The message element is a string of content to render if the $type returns FALSE.
123 *
124 * @ingroup mysite_hooks
125 */
126 function mysite_type_hook_active($type) {
127 // some users must be allowed to view content, otherwise, give a configuration message
128 $result = db_query("SELECT perm FROM {permission}");
129 $check = '';
130 while ($perms = db_fetch_object($result)) {
131 $check .= $perms->perm;
132 }
133 if (stristr($check, 'access content')) {
134 $value = TRUE;
135 }
136 else {
137 $value = FALSE;
138 $message = l(t('No users have permission to access site content'), 'admin/user/access');
139 }
140 return array($type => $value, 'message' => $message);
141 }
142
143 /**
144 * Sets the content selection options for this type.
145 *
146 * The plugin must find the active and allowed content options that users may add to their personal MySite page.
147 * Typically, this is done by pulling back all id keys for a given category.
148 *
149 * Invoked by mysite_type_hook().
150 *
151 * @return
152 * An array of options for this type. These define the content that can be added to a MySite collection. The array is
153 * an associative array with [n] levels. Elements include:
154 * - 'group': String. An name for the parent element of this content. Optional. Used with hierarchical content like taxonomies. See mysite_type_term_options() for an example.
155 * - 'name': String. The default display name for this content. Required. Calls mysite_type_hook_title() in order to add the prefix and suffix values defined by mysite_type_hook().
156 * - 'type_id': Numeric. This is the native id key for the content, such as the term id (tid) for a taxonomy term. Required.
157 * - 'type': String. The content type, usually identical to the name of the include. Required.
158 * - 'icon': Special. Invokes mysite_get_icon() to return the browser icon for this content, if the mysite_icon.module is enabled. Required. This value will either be a string indicating the filename of a MySite Icon upload or an array indicating the path and filename of another file. See mysite_type_user_options() for an example.
159 *
160 * @ingroup mysite_hooks
161 */
162 function mysite_type_hook_options() {
163 $options = array();
164 $sql = "SELECT m.id, m.title, g.group FROM {mytable} m INNER JOIN {group} g ON m.id = g.id";
165 $result = db_query($sql);
166 $items = array();
167 while ($item = db_fetch_object($result)) {
168 $items[] =$item;
169 }
170 foreach ($items as $key => $value) {
171 $options['group'][] = $value->group;
172 $options['name'][] = mysite_type_hook_title($value->id, $value->title);
173 $options['type_id'][] = $value->id;
174 $options['type'][] = 'hook';
175 $options['icon'][] = mysite_get_icon('hook', $value->id);
176 }
177 return $options;
178 }
179
180 /**
181 * Returns the title of a content element.
182 *
183 * This hook has two uses. First, it lets us return a title element based on a given type and id. Second, it adds the prefix and suffix strings from mysite_type_hook() to the name element.
184 *
185 * Invoked by:
186 * - mysite_content_add()
187 * - mysite_block_handler()
188 * - mysite_type_hook_options()
189 *
190 * @param $type_id
191 * The numeric identifier for this element. Required.
192 * @param $title
193 * The title string to display. Optional. If present, the prefix and suffix from mysite_type_hook() will be added.
194 * @return
195 * The prepared title string.
196 *
197 * @ingroup mysite_hooks
198 */
199 function mysite_type_hook_title($type_id = NULL, $title = NULL) {
200 if (!empty($type_id)) {
201 if (is_null($title)) {
202 $sql = "SELECT title FROM {mytable} WHERE id = %d ORDER BY title";
203 $title = db_result(db_query($sql, $type_id));
204 }
205 $type = mysite_type_hook(FALSE);
206 $title = $type['prefix'] .' '. $title .' '. $type['suffix'];
207 $title = trim(rtrim($title));
208 return $title;
209 }
210 drupal_set_message(t('Could not find type title'), 'error');
211 return;
212 }
213
214 /**
215 * Returns the data for a requested content element.
216 *
217 * This is the core MySite page content function. It is used to return the items to display on a user's personal page.
218 * For each content element on the page, this function is invoked, passing the $type_id to retrieve the appropriate content.
219 *
220 * NOTE: When pulling back node content, be sure to wrap the database call in db_rewrite_sql() in order to respect node_access rules.
221 *
222 * NOTE: MySite does not use hook_view() for node content because we don't assume that all MySite content elements are nodes. Since we want the data array to be standardized (and since we have our own Format functions), custom node templates are not invoked.
223 *
224 * NOTE: For easier theming by the Layout and Format plugins, we do output filter routines on the data within this function.
225 *
226 * Invoked by mysite_page().
227 *
228 * @param $type_id
229 * The numeric identifier for this element. Required. Set to NULL for a logic check.
230 * @param $settings
231 * User-specific settings for this content type, if applicable. Optional. See profile.inc for an example usage.
232 * @return
233 * An array of information about this content element, used to render the output. The array is [n] levels deep (even if n == 1), with an associative array at each level and some 'parent' data at the top of the array. Returns an error message on failure. The data is returned in the format:
234 * - 'base': The Drupal path or a full URL to the data source. Used to link to "read more." Optional.
235 * - 'xml': The Drupal path or a full URL to an XML/RSS/ATOM feed. Not currently implemented. Optional.
236 * - 'image': An optional image to display, typically an RSS image for a feed. Optional. See mysite_type_feed_data() for and example.
237 * - [n] 'type': The content type. Usually the same as the plugin name. Required.
238 * - [n] 'link': A full <a href="path">Title</a> HTML string, usually generated by Drupal's l() function. Required.
239 * - [n] 'title': The plain-text title of the item. Required. You must use check_plain() here.
240 * - [n] 'subtitle': The plain-text subtitle of the item, typically the source name. Optional. Use check_plain().
241 * - [n] 'date': The UNIX timestamp of the last update for the item. Optional.
242 * - [n] 'uid': The Drupal user id of the item's author. Optional.
243 * - [n] 'author': The username of the item's author. Optional. You must use check_plain() here.
244 * - [n] 'teaser': The teaser element to display. Optional. Node items should use mysite_teaser() to ensure proper filtering.
245 * - [n] 'content': An HTML content element that should be used for the whole content item. Optional. This feature is used by MySite Droplets to render Block and View content. If the 'content' element is present, it will be printed and other data (like 'teaser') may not. See mysite_type_droplet_data() for an example.
246 * - [n] 'nid': The node id of the item. Optional.
247 *
248 * @ingroup mysite_hooks
249 */
250 function mysite_type_hook_data($type_id = NULL, $settings = NULL) {
251 if (!empty($type_id)) {
252 $sql = db_rewrite_sql("SELECT n.nid, n.changed FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid WHERE t.nid = %d AND n.status = 1 ORDER BY n.changed DESC");
253 $result = db_query_range($sql, $type_id, 0, variable_get('mysite_elements', 5));
254 $data = array(
255 'base' => '',
256 'xml' => '',
257 'image' => '',
258 );
259 $items = array();
260 $i = 0;
261 $type = mysite_type_hook(FALSE);
262 while ($nid = db_fetch_object($result)) {
263 $node = node_load($nid->nid);
264 $items[$i]['type'] = $node->type;
265 $items[$i]['link'] = l($node->title, 'node/'. $nid->nid, array('target' => $type['link_target']));
266 $items[$i]['title'] = check_plain($node->title);
267 $items[$i]['subtitle'] = NULL;
268 $items[$i]['date'] = $node->changed;
269 $items[$i]['uid'] = $node->uid;
270 $items[$i]['author'] = check_plain($node->name);
271 $items[$i]['teaser'] = mysite_teaser($node);
272 $items[$i]['content'] = NULL;
273 $items[$i]['nid'] = $node->nid;
274 $i++;
275 }
276 $data['items'] = $items;
277 return $data;
278 }
279 drupal_set_message(t('Could not find type data'), 'error');
280 return;
281 }
282
283 /**
284 * Returns content to add to the MySite block.
285 *
286 * This function checks the page that the user is on and returns MySite actions appropriate to the current path. While the return value is an HTML string, the $data array passed to mysite_block_handler() is key here.
287 * The $data array takes the format:
288 * - 'uid': The user id of the person viewing the page.
289 * - 'type': The content type defined by this include.
290 * - 'type_id': The id key for this particular page. That is, if viewing 'taxonomy/term/2', this value is '2'.
291 *
292 * NOTE: As of 5.x.3, we no longer pass the 'title' element here. It is checked inside mysite_block_handler().
293 *
294 * NOTE: The call to mysite_block_handler() is here rather than within mysite_block() in case the initial IF check fails. Doing so saves us needless function calls.
295 *
296 * NOTE: In theory, you could add additional HTML to the $content, but mysite_block is expecting to receive the <ul><li>link to action</li></ul> content generated by mysite_block_handler(). Therefore, adding extra HTML is not recommended.
297 *
298 * NOTE: This function does not handle block content for node pages. See mysite_type_hook_block_node().
299 *
300 * See mysite_type_user_block() and mysite_type_term_block() for examples.
301 *
302 * Invoked by mysite_block().
303 *
304 * @param $arg
305 * An array generated by mysite_block(). Consists of arg(0) through arg(5). Prevents calling arg() multiple times during the hook.
306 * @param $op
307 * The block operation ($op) being performed. Always 'view'. Deprecated.
308 * @return
309 * An HTML string to append to the MySite block, formatted by mysite_block_handler().
310 *
311 * @ingroup mysite_hooks
312 */
313 function mysite_type_hook_block($arg, $op = 'view') {
314 global $user;
315 if (user_access('access content') && ($arg[0] == 'mypath' && is_numeric($arg[1]))) {
316 $data = array();
317 $data['uid'] = $user->uid;
318 $data['type'] = 'hook';
319 $data['type_id'] = $arg[1];
320 $content = mysite_block_handler($data);
321 return $content;
322 }
323 }
324
325 /**
326 * Returns block content when viewing a node page.
327 *
328 * Node pages are a special case, since mysite_type_hook_block() assumes that arg(1) is a unique content key. For nodes, arg(1) is the node id, so we use this hook instead.
329 *
330 * See mysite_type_hook_block() for details on the $data array passed to mysite_block_handler().
331 *
332 * Invoked by mysite_block().
333 *
334 * @param $nid
335 * The node id of the page being viewed.
336 * @param $type
337 * The node type of the page being viewed.
338 * @return
339 * The content to be displayed by mysite_block(), formatted by mysite_block_handler().
340 *
341 * @ingroup mysite_hooks
342 */
343 function mysite_type_hook_block_node($nid, $type) {
344 if ($type == 'mynodetype') {
345 global $user;
346 $id = db_result(db_query("SELECT id FROM {mytable} WHERE nid = %d", $nid));
347 $data = array();
348 $data['uid'] = $user->uid;
349 $data['type'] = $type;
350 $data['type_id'] = $id;
351 $content = mysite_block_handler($data);
352 return $content;
353 }
354 }
355
356 /**
357 * Searches options for a given type.
358 *
359 * Designed to let users search the data provided by mysite_type_hook_options().
360 *
361 * Invoked by mysite_get_content_element().
362 *
363 * @param $uid
364 * The user id of the user performing the search. Value is passed from mysite_get_content_element().
365 * @return
366 * A search form generated via FormsAPI using mysite_type_hook_search_form().
367 *
368 * @ingroup mysite_hooks
369 */
370 function mysite_type_hook_search($uid = NULL) {
371 if (!is_null($uid)) {
372 $output .= drupal_get_form('mysite_type_hook_search_form', $uid);
373 return $output;
374 }
375 }
376
377 /**
378 * FormsAPI for mysite_type_hook_search()
379 *
380 * This form is designed for simple searching of a content group. It should have a title element, hidden values for 'uid' and 'type' and a named 'submit' button.
381 *
382 * The form will be processed by mysite_type_hook_search_form_submit().
383 *
384 * NOTE: If you need more elaborate forms for special functions, use mysite_type_hook_form().
385 *
386 * @param $uid
387 * The id of the user performing the search.
388 *
389 * @return
390 * A form according to FormsAPI.
391 *
392 * @ingroup mysite_hooks
393 */
394 function mysite_type_hook_search_form($uid) {
395 $form['add_hook']['hook_title'] = array('#type' => 'textfield',
396 '#title' => t('Search title'),
397 '#default_value' => $edit['hook_title'],
398 '#maxlength' => 64,
399 '#size' => 40,
400 '#description' => t('Search form description.'),
401 '#required' => TRUE,
402 '#autocomplete_path' => 'autocomplete/mysite/hook'
403 );
404 $form['add_hook']['uid'] = array('#type' => 'hidden', '#value' => $uid);
405 $form['add_hook']['type'] = array('#type' => 'hidden', '#value' => 'hook');
406 $form['add_hook']['submit'] = array('#type' => 'submit', '#value' => t('Add Hook Name'));
407 return $form;
408 }
409
410 /**
411 * Form submit handler for mysite_type_hook_search().
412 *
413 * The purpose of this function is to find matches to the user's search. An array of matches is then passed to mysite_search_handler() in order to display the proper options and messages to the user.
414 *
415 * While function has no return value, it really uses mysite_search_handler() to respond to the form. This function must pass a $data array that is an associative array that is [n] levels deep.
416 * - [n] 'uid': The user id of the person whose MySite page is being updated.
417 * - [n] 'type': The content type being searched.
418 * - [n] 'type_id': The id key for the content type.
419 * - [n] 'title': The title of the content item, derived using mysite_type_hook_title().
420 * - [n] 'description': A short description of the content item.
421 *
422 * Invoked by mysite_type_hook_search_form().
423 *
424 * @param $form_id
425 * The form_id defined in FormsAPI, passed by mysite_type_hook_search().
426 * @param $form_values
427 * An array of data passed by the form according to the FormsAPI.
428 *
429 * @ingroup mysite_hooks
430 */
431 function mysite_type_hook_search_form_submit($form_id, $form_values) {
432 // we use LIKE here in case JavaScript autocomplete support doesn't work.
433 // or in case the user doesn't autocomplete the form
434 $result = db_query("SELECT id, title FROM {mytable} WHERE title LIKE LOWER('%s%%')", $form_values['hook_title']);
435 $count = 0;
436 while ($item = db_fetch_object($result)) {
437 $data[$count]['uid'] = $form_values['uid'];
438 $data[$count]['type'] = $form_values['type'];
439 $data[$count]['type_id'] = $item->id;
440 $data[$count]['title'] = mysite_type_hook_title($item->id, $item->title);
441 $data[$count]['description'] = t('Description of @title', array('@title' => $item->title));
442 $count++;
443 }
444 // pass the $data to the universal handler
445 mysite_search_handler($data, 'hook');
446 return;
447 }
448
449 /**
450 * AJAX autocomplete for aggregator titles.
451 *
452 * Since plugins don't have their own menu items, we pass all autocomplete requests through
453 * mysite_autocomplete, which then invokes this internal hook.
454 *
455 * See http://drupal.org/node/42552 for additional information about AJAX autocomplete.
456 *
457 * Invoked by mysite_autocomplete().
458 *
459 * @param $string
460 * The search string entered by the user.
461 * @return
462 * An array of items that matched the search routine.
463 *
464 * @ingroup mysite_hooks
465 */
466 function mysite_type_hook_autocomplete($string) {
467 $matches = array();
468 $result = db_query_range("SELECT id, title FROM {mytable} WHERE title LIKE LOWER('%s%%')", $string, 0, 10);
469 while ($data = db_fetch_object($result)) {
470 $matches[$data->title] = check_plain($data->title);
471 }
472 return $matches;
473 }
474
475 /**
476 * Cron cleanup function.
477 *
478 * Since plugins are only included dynamically, we can't put hook_cron() functions directly into type includes.
479 * Instead we invoke them using the mysite_type_hook_clear() function.
480 *
481 * The function should check to see that all type_id keys stored by users are still active in the parent database. For example,
482 * the mysite_type_user_clear() function checks to see that all user ids stored in the {mysite_data} table are still active users
483 * of the site.
484 *
485 * If this function finds no illegal data, it will return (correctly) an empty array.
486 *
487 * Invoked by mysite_cron().
488 *
489 * @param $type
490 * The content type passed by mysite_cron().
491 * @return
492 * An array of items to delete from all user MySite pages.
493 * The key is the mysite_id (mid) and the value is the corresponding data from {mysite_data}
494 *
495 * @ingroup mysite_hooks
496 */
497 function mysite_type_hook_clear($type) {
498 // fetch all the active records of this type and see if they really exist in the proper table
499 $sql = "SELECT mid, uid, type_id, title FROM {mysite_data} WHERE type = '%s'";
500 $result = db_query($sql, $type);
501 $data = array();
502 while ($item = db_fetch_array($result)) {
503 $sql = "SELECT id FROM {mytable} WHERE id = %d";
504 $check = db_fetch_object(db_query($sql, $item['type_id']));
505 if (empty($check->id)) {
506 $data[$item['mid']] = $item;
507 }
508 }
509 return $data;
510 }
511
512 /**
513 * Add a form element distinct to a content type
514 *
515 * This hook is used when content types need to add a special form to the MySite Content page. Used specifically by the feed.inc plugin to allow users to add RSS/ATOM feeds.
516 * See mysite_type_feed_form() for usage example.
517 *
518 * The form that you implement should have the normal FormsAPI elements of _form, _validate, and _submit.
519 *
520 * Invoked by mysite_get_content_element().
521 *
522 * @param $param
523 * You may pass any parameters that can be received by your implementation of mysite_type_hook_custom_form().
524 * @return
525 * HTML generated by drupal_get_form()
526 *
527 * @ingroup mysite_hooks
528 */
529 function mysite_type_hook_form($param) {
530 if (user_access('mypermission')) {
531 $output = '<p>'. t('User message.') .'</p>';
532 $output .= drupal_get_form('mysite_type_hook_custom_form', $param);
533 }
534 return $output;
535 }
536
537 /**
538 * FormsAPI for mysite_type_hook_custom_form()
539 *
540 * @param $param
541 * Any parameters passed by mysite_type_hook_form().
542 * @return
543 * An array conforming to the FormsAPI
544 *
545 * @ingroup mysite_hooks
546 */
547 function mysite_type_feed_custom_form($param) {
548 $form['new_feed'] = array(
549 '#type' => 'textfield',
550 '#title' => t('Form element'),
551 '#title' => t('Your Field Name'),
552 '#size' => 40
553 );
554 return $form;
555 }
556
557 /**
558 * Register changes to MySite page.
559 *
560 * When the user updates a MySite page, this hook allows type plugins to
561 * register any needed changes. See path.inc for an example.
562 *
563 * @param
564 * $uid == the user id of the owner of the MySite page.
565 *
566 * @ingroup mysite_hooks
567 */
568 function mysite_type_hook_updated($uid) {
569 if (!empty($uid)) {
570 db_query("UPDATE {mytable} SET last_visit = %d WHERE uid = %d", time(), $uid);
571 }
572 }
573
574 /**
575 * Content settings hook.
576 *
577 * Allows plugins to add elements to a content configuration form.
578 *
579 * Invoked by mysite_content_settings_form().
580 *
581 * @param $data
582 * Array with information from the {mysite_data} table for this given content.
583 * @return
584 * An array of elements formatted according to the Drupal FormsAPI. These will be appended to
585 * the main form and do not require submit functions. When naming form elements, be careful
586 * of possible namespace collisions.
587 *
588 * @ingroup mysite_hooks
589 */
590 function mysite_type_hook_content_form($data) {
591 $extra['myvalue'] = array(
592 '#type' => 'textfield',
593 '#size' => 40,
594 '#maxlength' => 80,
595 '#title' => 'test'
596 );
597 return $extra;
598 }
599
600 /**
601 * Content settings validation hook.
602 *
603 * Allows plugins to validate elements added to a content configuration form. See
604 * mysite_type_profile_content_form_validate() for an example.
605 *
606 * Invoked by mysite_content_settings_form_validate().
607 *
608 * @param $form_values
609 * Array of data passed by mysite_content_settings_form().
610 *
611 * @ingroup mysite_hooks
612 */
613 function mysite_type_hook_content_form_validate($form_values) {
614 if (empty($form_values['myvalue'])) {
615 form_set_error('myvalue', t('myvalue is required'));
616 }
617 }
618
619 /**
620 * Content settings submit hook.
621 *
622 * Allows plugins to act on elements added to a content configuration form. See
623 * mysite_type_profile_content_form_submit() for an example.
624 *
625 * It is assumed that these values will be saved as a serialized array in the {mysite_data}
626 * column for the given mid element. These user-specific settings allow the mysite_type_hook_data()
627 * function to customize content output on a per-user basis.
628 *
629 * NOTE: Be sure to name the keys so that the data can be understood when invoked
630 * by the mysite_type_hook_data() function.
631 *
632 * Invoked by mysite_content_settings_form_submit().
633 *
634 * @param $form_values
635 * Array of data passed by mysite_content_settings_form().
636 *
637 * @ingroup mysite_hooks
638 */
639 function mysite_type_hook_content_form_submit($form_values) {
640 $save = array('myvalue' => $form_values['myvalue']);
641 $settings = serialize($save);
642 db_query("UPDATE {mysite_data} SET settings = '%s' WHERE mid = %d", $settings, $form_values['mid']);
643 drupal_set_message(t('Personal settings saved.'));
644 }
645
646 /**
647 * Defines the layout theme for a user's MySite page.
648 *
649 * This function takes the data for a user's MySite page and passes it to the selected layout file for display.
650 *
651 * Pay careful attention to the CSS ids and classes, as they are used by mysite.css and mysite.js to enable collapse and drag-and-drop sorting functions.
652 *
653 * Invoked by mysite_page(). Invokes theme_mysite_hook_item().
654 *
655 * @param $content
656 * An array of content to display. This content consists of up to 4 sub-array elements:
657 * 'owner' == the $user object of the owner of this MySIte page.
658 * 'mysite' == information about this MySite page from mysite_get().
659 * 'data' == the content data to display, from mysite_type_hook_data(). This data will be formatted by the selected format file.
660 * 'header' == used to display any messages waiting for the user.
661 * @return
662 * A themed page view.
663 *
664 * @ingroup mysite_hooks
665 */
666 function theme_mysite_hook_layout($content) {
667 // break the array into pieces
668 $owner = $content['owner'];
669 $mysite = $content['mysite'];
670 $columns = mysite_layout_default();
671 $data = mysite_prepare_columns($mysite, $content['data'], $columns['count']);
672 $header = $content['header'];
673 // print the header message, if present
674 if (isset($header)) {
675 $output = '<div class="messages">'. $header .'</div>';
676 }
677 // ajax-generated message class
678 $output .= '<div class="mysite-ajax"></div>';
679 $output .= '<div class="mysite-sortable mysite-full-width" id="mysite-sort0">';
680 // cycle through the data
681 foreach ($data as $key => $value) {
682 if ($value['mid']) {
683 $output .= '<div class="mysite-group collapsible sortable-item" id="m'. $value['mid'] .'">';
684 }
685 else {
686 $output .= '<div class="mysite-group">';
687 }
688 $output .= '<span class="mysite-header">'. $value['title'] .'</span>';
689 $output .= '<div class="mysite-content">';
690 if (!empty($value['output'])) {
691 if (!empty($value['output']['image'])) {
692 $output .= $value['output']['image'];
693 }
694 $output .= theme('mysite_'. $value['format'] .'_item', $value['output']['items']);
695 }
696 else {
697 $output .= t('<p>No content found.</p>');
698 }
699 $output .= '</div>';
700 $output .= '<div class="mysite-footer">';
701 if (!empty($value['output']['base'])) {
702 $output .= '<div class="mysite-footer-left">'. l(t('Read more'), $value['output']['base']) .'</div>';
703 }
704 $output .= ' <div class="mysite-footer-right">'. $value['actions'] .'</div> ';
705 $output .= '</div>';
706 $output .= '</div>';
707 }
708 $output .= '</div>';
709 print theme('page', $output, variable_get('mysite_fullscreen', 1));
710 return;
711 }
712
713 /**
714 * Information about this layout.
715 *
716 * This hook is used to help display information about the layout to the end user. It is also used to calculate the number of page regions to generate.
717 *
718 * Invoked by mysite_prepare_columns() and mysite_edit_form().
719 *
720 * @return
721 * An array of data containing the following elements:
722 * - 'regions' == a positional array of named regions (similar to PHPTemplate regions) that will be shown to the end user.
723 * - 'count' == the number of regions in the layout.
724 * - 'name' == the layout name to present to the end user.
725 * - 'description' == a description of the layout shown to the end user.
726 * - 'image' == the name of the preview image used to represent this layout.
727 *
728 * @ingroup mysite_hooks
729 */
730 function mysite_layout_hook() {
731 $data = array();
732 $data['regions'] = array('0' => t('Left'), '1' => t('Right'));
733 $data['count'] = count($data['regions']);
734 $data['name'] = t('My Layout');
735 $data['description'] = t('A description of the layout.');
736 $data['image'] = 'mylayout.png';
737 return $data;
738 }
739
740 /**
741 * Theme function hook for a content format.
742 *
743 * The MySite format files can choose to display any or all of the data supplied by mysite_type_hook_data().
744 *
745 * If the 'content' element of the array is present, the content item presents a single HTML block and should be printed in all cases.
746 *
747 * Invoked by mysite_theme_hook_layout().
748 *
749 * @param $item
750 * An array of content to display in a MySite content element. An element of the array defined by mysite_type_hook_data().
751 * @return $output
752 * HTML content to be rendered.
753 *
754 * @ingroup mysite_hooks
755 */
756 function theme_mysite_hook_item($item) {
757 $output = '';
758 foreach ($item as $element) {
759 // if this is not a droplet, then build a content view
760 if (empty($element['content'])) {
761 $output .= '<h4>'. $element['link'] .'</h4>';
762 if (!empty($element['subtitle'])) {
763 $output .= '<div class="mysite-subtitle">&raquo; '. $element['subtitle'] .'</div>';
764 }
765 if (!empty($element['author'])) {
766 $output .= '<div class="mysite-submitted">';
767 $output .= t('submitted by !author on !time', array('!author' => $element['author'], '!time' => format_date(time(), 'medium')));
768 $output .= '</div>';
769 }
770 $output .= $element['teaser'];
771 }
772 // this is a droplet, so output the content
773 else {
774 $output = theme('mysite_droplet', $element['content']);
775 }
776 }
777 return $output;
778 }
779
780 /**
781 * Format definition hook.
782 *
783 * Used by theme files to display sample formatting, this function registers a format file with MySite.
784 *
785 * Invoked by mysite_edit_form() and mysite_content_settings_form().
786 *
787 * @return
788 * An array containing the format name and the HTML output formatted according the the pattern defined in the hook.
789 *
790 * @ingroup mysite_hooks
791 */
792 function mysite_theme_hook() {
793 $name = t('Format name');
794 $output .= '<div class="mysite-sample mysite-content">';
795 $output .= t('<h2><a href="#">Sample headline</a></h2>');
796 $output .= t('submitted by johndoe on !time', array('!time' => format_date($element['date'], 'medium')));
797 $output .= t('Sample layout text, including HTML formatting');
798 $output .= '</div>';
799 return array('format' => $name, 'sample' => $output);
800 }

  ViewVC Help
Powered by ViewVC 1.1.2