annotate modules/node/node.api.php @ 0:ff03f76ab3fe

initial version
author danieleb <danielebarchiesi@me.com>
date Wed, 21 Aug 2013 18:51:11 +0100
parents
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2
danielebarchiesi@0 3 /**
danielebarchiesi@0 4 * @file
danielebarchiesi@0 5 * Hooks provided by the Node module.
danielebarchiesi@0 6 */
danielebarchiesi@0 7
danielebarchiesi@0 8 /**
danielebarchiesi@0 9 * @defgroup node_api_hooks Node API Hooks
danielebarchiesi@0 10 * @{
danielebarchiesi@0 11 * Functions to define and modify content types.
danielebarchiesi@0 12 *
danielebarchiesi@0 13 * Each content type is maintained by a primary module, which is either
danielebarchiesi@0 14 * node.module (for content types created in the user interface) or the module
danielebarchiesi@0 15 * that implements hook_node_info() to define the content type.
danielebarchiesi@0 16 *
danielebarchiesi@0 17 * During node operations (create, update, view, delete, etc.), there are
danielebarchiesi@0 18 * several sets of hooks that get invoked to allow modules to modify the base
danielebarchiesi@0 19 * node operation:
danielebarchiesi@0 20 * - Node-type-specific hooks: These hooks are only invoked on the primary
danielebarchiesi@0 21 * module, using the "base" return component of hook_node_info() as the
danielebarchiesi@0 22 * function prefix. For example, poll.module defines the base for the Poll
danielebarchiesi@0 23 * content type as "poll", so during creation of a poll node, hook_insert() is
danielebarchiesi@0 24 * only invoked by calling poll_insert().
danielebarchiesi@0 25 * - All-module hooks: This set of hooks is invoked on all implementing modules,
danielebarchiesi@0 26 * to allow other modules to modify what the primary node module is doing. For
danielebarchiesi@0 27 * example, hook_node_insert() is invoked on all modules when creating a poll
danielebarchiesi@0 28 * node.
danielebarchiesi@0 29 * - Field hooks: Hooks related to the fields attached to the node. These are
danielebarchiesi@0 30 * invoked from the field operations functions described below, and can be
danielebarchiesi@0 31 * either field-type-specific or all-module hooks.
danielebarchiesi@0 32 * - Entity hooks: Generic hooks for "entity" operations. These are always
danielebarchiesi@0 33 * invoked on all modules.
danielebarchiesi@0 34 *
danielebarchiesi@0 35 * Here is a list of the node and entity hooks that are invoked, field
danielebarchiesi@0 36 * operations, and other steps that take place during node operations:
danielebarchiesi@0 37 * - Creating a new node (calling node_save() on a new node):
danielebarchiesi@0 38 * - field_attach_presave()
danielebarchiesi@0 39 * - hook_node_presave() (all)
danielebarchiesi@0 40 * - hook_entity_presave() (all)
danielebarchiesi@0 41 * - Node and revision records are written to the database
danielebarchiesi@0 42 * - hook_insert() (node-type-specific)
danielebarchiesi@0 43 * - field_attach_insert()
danielebarchiesi@0 44 * - hook_node_insert() (all)
danielebarchiesi@0 45 * - hook_entity_insert() (all)
danielebarchiesi@0 46 * - hook_node_access_records() (all)
danielebarchiesi@0 47 * - hook_node_access_records_alter() (all)
danielebarchiesi@0 48 * - Updating an existing node (calling node_save() on an existing node):
danielebarchiesi@0 49 * - field_attach_presave()
danielebarchiesi@0 50 * - hook_node_presave() (all)
danielebarchiesi@0 51 * - hook_entity_presave() (all)
danielebarchiesi@0 52 * - Node and revision records are written to the database
danielebarchiesi@0 53 * - hook_update() (node-type-specific)
danielebarchiesi@0 54 * - field_attach_update()
danielebarchiesi@0 55 * - hook_node_update() (all)
danielebarchiesi@0 56 * - hook_entity_update() (all)
danielebarchiesi@0 57 * - hook_node_access_records() (all)
danielebarchiesi@0 58 * - hook_node_access_records_alter() (all)
danielebarchiesi@0 59 * - Loading a node (calling node_load(), node_load_multiple() or entity_load()
danielebarchiesi@0 60 * with $entity_type of 'node'):
danielebarchiesi@0 61 * - Node and revision information is read from database.
danielebarchiesi@0 62 * - hook_load() (node-type-specific)
danielebarchiesi@0 63 * - field_attach_load_revision() and field_attach_load()
danielebarchiesi@0 64 * - hook_entity_load() (all)
danielebarchiesi@0 65 * - hook_node_load() (all)
danielebarchiesi@0 66 * - Viewing a single node (calling node_view() - note that the input to
danielebarchiesi@0 67 * node_view() is a loaded node, so the Loading steps above are already done):
danielebarchiesi@0 68 * - hook_view() (node-type-specific)
danielebarchiesi@0 69 * - field_attach_prepare_view()
danielebarchiesi@0 70 * - hook_entity_prepare_view() (all)
danielebarchiesi@0 71 * - field_attach_view()
danielebarchiesi@0 72 * - hook_node_view() (all)
danielebarchiesi@0 73 * - hook_entity_view() (all)
danielebarchiesi@0 74 * - hook_node_view_alter() (all)
danielebarchiesi@0 75 * - hook_entity_view_alter() (all)
danielebarchiesi@0 76 * - Viewing multiple nodes (calling node_view_multiple() - note that the input
danielebarchiesi@0 77 * to node_view_multiple() is a set of loaded nodes, so the Loading steps
danielebarchiesi@0 78 * above are already done):
danielebarchiesi@0 79 * - field_attach_prepare_view()
danielebarchiesi@0 80 * - hook_entity_prepare_view() (all)
danielebarchiesi@0 81 * - hook_view() (node-type-specific)
danielebarchiesi@0 82 * - field_attach_view()
danielebarchiesi@0 83 * - hook_node_view() (all)
danielebarchiesi@0 84 * - hook_entity_view() (all)
danielebarchiesi@0 85 * - hook_node_view_alter() (all)
danielebarchiesi@0 86 * - hook_entity_view_alter() (all)
danielebarchiesi@0 87 * - Deleting a node (calling node_delete() or node_delete_multiple()):
danielebarchiesi@0 88 * - Node is loaded (see Loading section above)
danielebarchiesi@0 89 * - hook_delete() (node-type-specific)
danielebarchiesi@0 90 * - hook_node_delete() (all)
danielebarchiesi@0 91 * - hook_entity_delete() (all)
danielebarchiesi@0 92 * - field_attach_delete()
danielebarchiesi@0 93 * - Node and revision information are deleted from database
danielebarchiesi@0 94 * - Deleting a node revision (calling node_revision_delete()):
danielebarchiesi@0 95 * - Node is loaded (see Loading section above)
danielebarchiesi@0 96 * - Revision information is deleted from database
danielebarchiesi@0 97 * - hook_node_revision_delete() (all)
danielebarchiesi@0 98 * - field_attach_delete_revision()
danielebarchiesi@0 99 * - Preparing a node for editing (calling node_form() - note that if it is an
danielebarchiesi@0 100 * existing node, it will already be loaded; see the Loading section above):
danielebarchiesi@0 101 * - hook_prepare() (node-type-specific)
danielebarchiesi@0 102 * - hook_node_prepare() (all)
danielebarchiesi@0 103 * - hook_form() (node-type-specific)
danielebarchiesi@0 104 * - field_attach_form()
danielebarchiesi@0 105 * - Validating a node during editing form submit (calling
danielebarchiesi@0 106 * node_form_validate()):
danielebarchiesi@0 107 * - hook_validate() (node-type-specific)
danielebarchiesi@0 108 * - hook_node_validate() (all)
danielebarchiesi@0 109 * - field_attach_form_validate()
danielebarchiesi@0 110 * - Searching (calling node_search_execute()):
danielebarchiesi@0 111 * - hook_ranking() (all)
danielebarchiesi@0 112 * - Query is executed to find matching nodes
danielebarchiesi@0 113 * - Resulting node is loaded (see Loading section above)
danielebarchiesi@0 114 * - Resulting node is prepared for viewing (see Viewing a single node above)
danielebarchiesi@0 115 * - comment_node_update_index() is called.
danielebarchiesi@0 116 * - hook_node_search_result() (all)
danielebarchiesi@0 117 * - Search indexing (calling node_update_index()):
danielebarchiesi@0 118 * - Node is loaded (see Loading section above)
danielebarchiesi@0 119 * - Node is prepared for viewing (see Viewing a single node above)
danielebarchiesi@0 120 * - hook_node_update_index() (all)
danielebarchiesi@0 121 * @}
danielebarchiesi@0 122 */
danielebarchiesi@0 123
danielebarchiesi@0 124 /**
danielebarchiesi@0 125 * @addtogroup hooks
danielebarchiesi@0 126 * @{
danielebarchiesi@0 127 */
danielebarchiesi@0 128
danielebarchiesi@0 129 /**
danielebarchiesi@0 130 * Inform the node access system what permissions the user has.
danielebarchiesi@0 131 *
danielebarchiesi@0 132 * This hook is for implementation by node access modules. In this hook,
danielebarchiesi@0 133 * the module grants a user different "grant IDs" within one or more
danielebarchiesi@0 134 * "realms". In hook_node_access_records(), the realms and grant IDs are
danielebarchiesi@0 135 * associated with permission to view, edit, and delete individual nodes.
danielebarchiesi@0 136 *
danielebarchiesi@0 137 * The realms and grant IDs can be arbitrarily defined by your node access
danielebarchiesi@0 138 * module; it is common to use role IDs as grant IDs, but that is not required.
danielebarchiesi@0 139 * Your module could instead maintain its own list of users, where each list has
danielebarchiesi@0 140 * an ID. In that case, the return value of this hook would be an array of the
danielebarchiesi@0 141 * list IDs that this user is a member of.
danielebarchiesi@0 142 *
danielebarchiesi@0 143 * A node access module may implement as many realms as necessary to properly
danielebarchiesi@0 144 * define the access privileges for the nodes. Note that the system makes no
danielebarchiesi@0 145 * distinction between published and unpublished nodes. It is the module's
danielebarchiesi@0 146 * responsibility to provide appropriate realms to limit access to unpublished
danielebarchiesi@0 147 * content.
danielebarchiesi@0 148 *
danielebarchiesi@0 149 * Node access records are stored in the {node_access} table and define which
danielebarchiesi@0 150 * grants are required to access a node. There is a special case for the view
danielebarchiesi@0 151 * operation -- a record with node ID 0 corresponds to a "view all" grant for
danielebarchiesi@0 152 * the realm and grant ID of that record. If there are no node access modules
danielebarchiesi@0 153 * enabled, the core node module adds a node ID 0 record for realm 'all'. Node
danielebarchiesi@0 154 * access modules can also grant "view all" permission on their custom realms;
danielebarchiesi@0 155 * for example, a module could create a record in {node_access} with:
danielebarchiesi@0 156 * @code
danielebarchiesi@0 157 * $record = array(
danielebarchiesi@0 158 * 'nid' => 0,
danielebarchiesi@0 159 * 'gid' => 888,
danielebarchiesi@0 160 * 'realm' => 'example_realm',
danielebarchiesi@0 161 * 'grant_view' => 1,
danielebarchiesi@0 162 * 'grant_update' => 0,
danielebarchiesi@0 163 * 'grant_delete' => 0,
danielebarchiesi@0 164 * );
danielebarchiesi@0 165 * drupal_write_record('node_access', $record);
danielebarchiesi@0 166 * @endcode
danielebarchiesi@0 167 * And then in its hook_node_grants() implementation, it would need to return:
danielebarchiesi@0 168 * @code
danielebarchiesi@0 169 * if ($op == 'view') {
danielebarchiesi@0 170 * $grants['example_realm'] = array(888);
danielebarchiesi@0 171 * }
danielebarchiesi@0 172 * @endcode
danielebarchiesi@0 173 * If you decide to do this, be aware that the node_access_rebuild() function
danielebarchiesi@0 174 * will erase any node ID 0 entry when it is called, so you will need to make
danielebarchiesi@0 175 * sure to restore your {node_access} record after node_access_rebuild() is
danielebarchiesi@0 176 * called.
danielebarchiesi@0 177 *
danielebarchiesi@0 178 * @see node_access_view_all_nodes()
danielebarchiesi@0 179 * @see node_access_rebuild()
danielebarchiesi@0 180 *
danielebarchiesi@0 181 * @param $account
danielebarchiesi@0 182 * The user object whose grants are requested.
danielebarchiesi@0 183 * @param $op
danielebarchiesi@0 184 * The node operation to be performed, such as 'view', 'update', or 'delete'.
danielebarchiesi@0 185 *
danielebarchiesi@0 186 * @return
danielebarchiesi@0 187 * An array whose keys are "realms" of grants, and whose values are arrays of
danielebarchiesi@0 188 * the grant IDs within this realm that this user is being granted.
danielebarchiesi@0 189 *
danielebarchiesi@0 190 * For a detailed example, see node_access_example.module.
danielebarchiesi@0 191 *
danielebarchiesi@0 192 * @ingroup node_access
danielebarchiesi@0 193 */
danielebarchiesi@0 194 function hook_node_grants($account, $op) {
danielebarchiesi@0 195 if (user_access('access private content', $account)) {
danielebarchiesi@0 196 $grants['example'] = array(1);
danielebarchiesi@0 197 }
danielebarchiesi@0 198 $grants['example_owner'] = array($account->uid);
danielebarchiesi@0 199 return $grants;
danielebarchiesi@0 200 }
danielebarchiesi@0 201
danielebarchiesi@0 202 /**
danielebarchiesi@0 203 * Set permissions for a node to be written to the database.
danielebarchiesi@0 204 *
danielebarchiesi@0 205 * When a node is saved, a module implementing hook_node_access_records() will
danielebarchiesi@0 206 * be asked if it is interested in the access permissions for a node. If it is
danielebarchiesi@0 207 * interested, it must respond with an array of permissions arrays for that
danielebarchiesi@0 208 * node.
danielebarchiesi@0 209 *
danielebarchiesi@0 210 * Node access grants apply regardless of the published or unpublished status
danielebarchiesi@0 211 * of the node. Implementations must make sure not to grant access to
danielebarchiesi@0 212 * unpublished nodes if they don't want to change the standard access control
danielebarchiesi@0 213 * behavior. Your module may need to create a separate access realm to handle
danielebarchiesi@0 214 * access to unpublished nodes.
danielebarchiesi@0 215 *
danielebarchiesi@0 216 * Note that the grant values in the return value from your hook must be
danielebarchiesi@0 217 * integers and not boolean TRUE and FALSE.
danielebarchiesi@0 218 *
danielebarchiesi@0 219 * Each permissions item in the array is an array with the following elements:
danielebarchiesi@0 220 * - 'realm': The name of a realm that the module has defined in
danielebarchiesi@0 221 * hook_node_grants().
danielebarchiesi@0 222 * - 'gid': A 'grant ID' from hook_node_grants().
danielebarchiesi@0 223 * - 'grant_view': If set to 1 a user that has been identified as a member
danielebarchiesi@0 224 * of this gid within this realm can view this node. This should usually be
danielebarchiesi@0 225 * set to $node->status. Failure to do so may expose unpublished content
danielebarchiesi@0 226 * to some users.
danielebarchiesi@0 227 * - 'grant_update': If set to 1 a user that has been identified as a member
danielebarchiesi@0 228 * of this gid within this realm can edit this node.
danielebarchiesi@0 229 * - 'grant_delete': If set to 1 a user that has been identified as a member
danielebarchiesi@0 230 * of this gid within this realm can delete this node.
danielebarchiesi@0 231 * - 'priority': If multiple modules seek to set permissions on a node, the
danielebarchiesi@0 232 * realms that have the highest priority will win out, and realms with a lower
danielebarchiesi@0 233 * priority will not be written. If there is any doubt, it is best to
danielebarchiesi@0 234 * leave this 0.
danielebarchiesi@0 235 *
danielebarchiesi@0 236 *
danielebarchiesi@0 237 * When an implementation is interested in a node but want to deny access to
danielebarchiesi@0 238 * everyone, it may return a "deny all" grant:
danielebarchiesi@0 239 *
danielebarchiesi@0 240 * @code
danielebarchiesi@0 241 * $grants[] = array(
danielebarchiesi@0 242 * 'realm' => 'all',
danielebarchiesi@0 243 * 'gid' => 0,
danielebarchiesi@0 244 * 'grant_view' => 0,
danielebarchiesi@0 245 * 'grant_update' => 0,
danielebarchiesi@0 246 * 'grant_delete' => 0,
danielebarchiesi@0 247 * 'priority' => 1,
danielebarchiesi@0 248 * );
danielebarchiesi@0 249 * @endcode
danielebarchiesi@0 250 *
danielebarchiesi@0 251 * Setting the priority should cancel out other grants. In the case of a
danielebarchiesi@0 252 * conflict between modules, it is safer to use hook_node_access_records_alter()
danielebarchiesi@0 253 * to return only the deny grant.
danielebarchiesi@0 254 *
danielebarchiesi@0 255 * Note: a deny all grant is not written to the database; denies are implicit.
danielebarchiesi@0 256 *
danielebarchiesi@0 257 * @see node_access_write_grants()
danielebarchiesi@0 258 *
danielebarchiesi@0 259 * @param $node
danielebarchiesi@0 260 * The node that has just been saved.
danielebarchiesi@0 261 *
danielebarchiesi@0 262 * @return
danielebarchiesi@0 263 * An array of grants as defined above.
danielebarchiesi@0 264 *
danielebarchiesi@0 265 * @see hook_node_access_records_alter()
danielebarchiesi@0 266 * @ingroup node_access
danielebarchiesi@0 267 */
danielebarchiesi@0 268 function hook_node_access_records($node) {
danielebarchiesi@0 269 // We only care about the node if it has been marked private. If not, it is
danielebarchiesi@0 270 // treated just like any other node and we completely ignore it.
danielebarchiesi@0 271 if ($node->private) {
danielebarchiesi@0 272 $grants = array();
danielebarchiesi@0 273 // Only published nodes should be viewable to all users. If we allow access
danielebarchiesi@0 274 // blindly here, then all users could view an unpublished node.
danielebarchiesi@0 275 if ($node->status) {
danielebarchiesi@0 276 $grants[] = array(
danielebarchiesi@0 277 'realm' => 'example',
danielebarchiesi@0 278 'gid' => 1,
danielebarchiesi@0 279 'grant_view' => 1,
danielebarchiesi@0 280 'grant_update' => 0,
danielebarchiesi@0 281 'grant_delete' => 0,
danielebarchiesi@0 282 'priority' => 0,
danielebarchiesi@0 283 );
danielebarchiesi@0 284 }
danielebarchiesi@0 285 // For the example_author array, the GID is equivalent to a UID, which
danielebarchiesi@0 286 // means there are many groups of just 1 user.
danielebarchiesi@0 287 // Note that an author can always view his or her nodes, even if they
danielebarchiesi@0 288 // have status unpublished.
danielebarchiesi@0 289 $grants[] = array(
danielebarchiesi@0 290 'realm' => 'example_author',
danielebarchiesi@0 291 'gid' => $node->uid,
danielebarchiesi@0 292 'grant_view' => 1,
danielebarchiesi@0 293 'grant_update' => 1,
danielebarchiesi@0 294 'grant_delete' => 1,
danielebarchiesi@0 295 'priority' => 0,
danielebarchiesi@0 296 );
danielebarchiesi@0 297
danielebarchiesi@0 298 return $grants;
danielebarchiesi@0 299 }
danielebarchiesi@0 300 }
danielebarchiesi@0 301
danielebarchiesi@0 302 /**
danielebarchiesi@0 303 * Alter permissions for a node before it is written to the database.
danielebarchiesi@0 304 *
danielebarchiesi@0 305 * Node access modules establish rules for user access to content. Node access
danielebarchiesi@0 306 * records are stored in the {node_access} table and define which permissions
danielebarchiesi@0 307 * are required to access a node. This hook is invoked after node access modules
danielebarchiesi@0 308 * returned their requirements via hook_node_access_records(); doing so allows
danielebarchiesi@0 309 * modules to modify the $grants array by reference before it is stored, so
danielebarchiesi@0 310 * custom or advanced business logic can be applied.
danielebarchiesi@0 311 *
danielebarchiesi@0 312 * @see hook_node_access_records()
danielebarchiesi@0 313 *
danielebarchiesi@0 314 * Upon viewing, editing or deleting a node, hook_node_grants() builds a
danielebarchiesi@0 315 * permissions array that is compared against the stored access records. The
danielebarchiesi@0 316 * user must have one or more matching permissions in order to complete the
danielebarchiesi@0 317 * requested operation.
danielebarchiesi@0 318 *
danielebarchiesi@0 319 * A module may deny all access to a node by setting $grants to an empty array.
danielebarchiesi@0 320 *
danielebarchiesi@0 321 * @see hook_node_grants()
danielebarchiesi@0 322 * @see hook_node_grants_alter()
danielebarchiesi@0 323 *
danielebarchiesi@0 324 * @param $grants
danielebarchiesi@0 325 * The $grants array returned by hook_node_access_records().
danielebarchiesi@0 326 * @param $node
danielebarchiesi@0 327 * The node for which the grants were acquired.
danielebarchiesi@0 328 *
danielebarchiesi@0 329 * The preferred use of this hook is in a module that bridges multiple node
danielebarchiesi@0 330 * access modules with a configurable behavior, as shown in the example with the
danielebarchiesi@0 331 * 'is_preview' field.
danielebarchiesi@0 332 *
danielebarchiesi@0 333 * @ingroup node_access
danielebarchiesi@0 334 */
danielebarchiesi@0 335 function hook_node_access_records_alter(&$grants, $node) {
danielebarchiesi@0 336 // Our module allows editors to mark specific articles with the 'is_preview'
danielebarchiesi@0 337 // field. If the node being saved has a TRUE value for that field, then only
danielebarchiesi@0 338 // our grants are retained, and other grants are removed. Doing so ensures
danielebarchiesi@0 339 // that our rules are enforced no matter what priority other grants are given.
danielebarchiesi@0 340 if ($node->is_preview) {
danielebarchiesi@0 341 // Our module grants are set in $grants['example'].
danielebarchiesi@0 342 $temp = $grants['example'];
danielebarchiesi@0 343 // Now remove all module grants but our own.
danielebarchiesi@0 344 $grants = array('example' => $temp);
danielebarchiesi@0 345 }
danielebarchiesi@0 346 }
danielebarchiesi@0 347
danielebarchiesi@0 348 /**
danielebarchiesi@0 349 * Alter user access rules when trying to view, edit or delete a node.
danielebarchiesi@0 350 *
danielebarchiesi@0 351 * Node access modules establish rules for user access to content.
danielebarchiesi@0 352 * hook_node_grants() defines permissions for a user to view, edit or delete
danielebarchiesi@0 353 * nodes by building a $grants array that indicates the permissions assigned to
danielebarchiesi@0 354 * the user by each node access module. This hook is called to allow modules to
danielebarchiesi@0 355 * modify the $grants array by reference, so the interaction of multiple node
danielebarchiesi@0 356 * access modules can be altered or advanced business logic can be applied.
danielebarchiesi@0 357 *
danielebarchiesi@0 358 * @see hook_node_grants()
danielebarchiesi@0 359 *
danielebarchiesi@0 360 * The resulting grants are then checked against the records stored in the
danielebarchiesi@0 361 * {node_access} table to determine if the operation may be completed.
danielebarchiesi@0 362 *
danielebarchiesi@0 363 * A module may deny all access to a user by setting $grants to an empty array.
danielebarchiesi@0 364 *
danielebarchiesi@0 365 * @see hook_node_access_records()
danielebarchiesi@0 366 * @see hook_node_access_records_alter()
danielebarchiesi@0 367 *
danielebarchiesi@0 368 * @param $grants
danielebarchiesi@0 369 * The $grants array returned by hook_node_grants().
danielebarchiesi@0 370 * @param $account
danielebarchiesi@0 371 * The user account requesting access to content.
danielebarchiesi@0 372 * @param $op
danielebarchiesi@0 373 * The operation being performed, 'view', 'update' or 'delete'.
danielebarchiesi@0 374 *
danielebarchiesi@0 375 * Developers may use this hook to either add additional grants to a user or to
danielebarchiesi@0 376 * remove existing grants. These rules are typically based on either the
danielebarchiesi@0 377 * permissions assigned to a user role, or specific attributes of a user
danielebarchiesi@0 378 * account.
danielebarchiesi@0 379 *
danielebarchiesi@0 380 * @ingroup node_access
danielebarchiesi@0 381 */
danielebarchiesi@0 382 function hook_node_grants_alter(&$grants, $account, $op) {
danielebarchiesi@0 383 // Our sample module never allows certain roles to edit or delete
danielebarchiesi@0 384 // content. Since some other node access modules might allow this
danielebarchiesi@0 385 // permission, we expressly remove it by returning an empty $grants
danielebarchiesi@0 386 // array for roles specified in our variable setting.
danielebarchiesi@0 387
danielebarchiesi@0 388 // Get our list of banned roles.
danielebarchiesi@0 389 $restricted = variable_get('example_restricted_roles', array());
danielebarchiesi@0 390
danielebarchiesi@0 391 if ($op != 'view' && !empty($restricted)) {
danielebarchiesi@0 392 // Now check the roles for this account against the restrictions.
danielebarchiesi@0 393 foreach ($restricted as $role_id) {
danielebarchiesi@0 394 if (isset($account->roles[$role_id])) {
danielebarchiesi@0 395 $grants = array();
danielebarchiesi@0 396 }
danielebarchiesi@0 397 }
danielebarchiesi@0 398 }
danielebarchiesi@0 399 }
danielebarchiesi@0 400
danielebarchiesi@0 401 /**
danielebarchiesi@0 402 * Add mass node operations.
danielebarchiesi@0 403 *
danielebarchiesi@0 404 * This hook enables modules to inject custom operations into the mass
danielebarchiesi@0 405 * operations dropdown found at admin/content, by associating a callback
danielebarchiesi@0 406 * function with the operation, which is called when the form is submitted. The
danielebarchiesi@0 407 * callback function receives one initial argument, which is an array of the
danielebarchiesi@0 408 * checked nodes.
danielebarchiesi@0 409 *
danielebarchiesi@0 410 * @return
danielebarchiesi@0 411 * An array of operations. Each operation is an associative array that may
danielebarchiesi@0 412 * contain the following key-value pairs:
danielebarchiesi@0 413 * - label: (required) The label for the operation, displayed in the dropdown
danielebarchiesi@0 414 * menu.
danielebarchiesi@0 415 * - callback: (required) The function to call for the operation.
danielebarchiesi@0 416 * - callback arguments: (optional) An array of additional arguments to pass
danielebarchiesi@0 417 * to the callback function.
danielebarchiesi@0 418 */
danielebarchiesi@0 419 function hook_node_operations() {
danielebarchiesi@0 420 $operations = array(
danielebarchiesi@0 421 'publish' => array(
danielebarchiesi@0 422 'label' => t('Publish selected content'),
danielebarchiesi@0 423 'callback' => 'node_mass_update',
danielebarchiesi@0 424 'callback arguments' => array('updates' => array('status' => NODE_PUBLISHED)),
danielebarchiesi@0 425 ),
danielebarchiesi@0 426 'unpublish' => array(
danielebarchiesi@0 427 'label' => t('Unpublish selected content'),
danielebarchiesi@0 428 'callback' => 'node_mass_update',
danielebarchiesi@0 429 'callback arguments' => array('updates' => array('status' => NODE_NOT_PUBLISHED)),
danielebarchiesi@0 430 ),
danielebarchiesi@0 431 'promote' => array(
danielebarchiesi@0 432 'label' => t('Promote selected content to front page'),
danielebarchiesi@0 433 'callback' => 'node_mass_update',
danielebarchiesi@0 434 'callback arguments' => array('updates' => array('status' => NODE_PUBLISHED, 'promote' => NODE_PROMOTED)),
danielebarchiesi@0 435 ),
danielebarchiesi@0 436 'demote' => array(
danielebarchiesi@0 437 'label' => t('Demote selected content from front page'),
danielebarchiesi@0 438 'callback' => 'node_mass_update',
danielebarchiesi@0 439 'callback arguments' => array('updates' => array('promote' => NODE_NOT_PROMOTED)),
danielebarchiesi@0 440 ),
danielebarchiesi@0 441 'sticky' => array(
danielebarchiesi@0 442 'label' => t('Make selected content sticky'),
danielebarchiesi@0 443 'callback' => 'node_mass_update',
danielebarchiesi@0 444 'callback arguments' => array('updates' => array('status' => NODE_PUBLISHED, 'sticky' => NODE_STICKY)),
danielebarchiesi@0 445 ),
danielebarchiesi@0 446 'unsticky' => array(
danielebarchiesi@0 447 'label' => t('Make selected content not sticky'),
danielebarchiesi@0 448 'callback' => 'node_mass_update',
danielebarchiesi@0 449 'callback arguments' => array('updates' => array('sticky' => NODE_NOT_STICKY)),
danielebarchiesi@0 450 ),
danielebarchiesi@0 451 'delete' => array(
danielebarchiesi@0 452 'label' => t('Delete selected content'),
danielebarchiesi@0 453 'callback' => NULL,
danielebarchiesi@0 454 ),
danielebarchiesi@0 455 );
danielebarchiesi@0 456 return $operations;
danielebarchiesi@0 457 }
danielebarchiesi@0 458
danielebarchiesi@0 459 /**
danielebarchiesi@0 460 * Respond to node deletion.
danielebarchiesi@0 461 *
danielebarchiesi@0 462 * This hook is invoked from node_delete_multiple() after the type-specific
danielebarchiesi@0 463 * hook_delete() has been invoked, but before hook_entity_delete and
danielebarchiesi@0 464 * field_attach_delete() are called, and before the node is removed from the
danielebarchiesi@0 465 * node table in the database.
danielebarchiesi@0 466 *
danielebarchiesi@0 467 * @param $node
danielebarchiesi@0 468 * The node that is being deleted.
danielebarchiesi@0 469 *
danielebarchiesi@0 470 * @ingroup node_api_hooks
danielebarchiesi@0 471 */
danielebarchiesi@0 472 function hook_node_delete($node) {
danielebarchiesi@0 473 db_delete('mytable')
danielebarchiesi@0 474 ->condition('nid', $node->nid)
danielebarchiesi@0 475 ->execute();
danielebarchiesi@0 476 }
danielebarchiesi@0 477
danielebarchiesi@0 478 /**
danielebarchiesi@0 479 * Respond to deletion of a node revision.
danielebarchiesi@0 480 *
danielebarchiesi@0 481 * This hook is invoked from node_revision_delete() after the revision has been
danielebarchiesi@0 482 * removed from the node_revision table, and before
danielebarchiesi@0 483 * field_attach_delete_revision() is called.
danielebarchiesi@0 484 *
danielebarchiesi@0 485 * @param $node
danielebarchiesi@0 486 * The node revision (node object) that is being deleted.
danielebarchiesi@0 487 *
danielebarchiesi@0 488 * @ingroup node_api_hooks
danielebarchiesi@0 489 */
danielebarchiesi@0 490 function hook_node_revision_delete($node) {
danielebarchiesi@0 491 db_delete('mytable')
danielebarchiesi@0 492 ->condition('vid', $node->vid)
danielebarchiesi@0 493 ->execute();
danielebarchiesi@0 494 }
danielebarchiesi@0 495
danielebarchiesi@0 496 /**
danielebarchiesi@0 497 * Respond to creation of a new node.
danielebarchiesi@0 498 *
danielebarchiesi@0 499 * This hook is invoked from node_save() after the database query that will
danielebarchiesi@0 500 * insert the node into the node table is scheduled for execution, after the
danielebarchiesi@0 501 * type-specific hook_insert() is invoked, and after field_attach_insert() is
danielebarchiesi@0 502 * called.
danielebarchiesi@0 503 *
danielebarchiesi@0 504 * Note that when this hook is invoked, the changes have not yet been written to
danielebarchiesi@0 505 * the database, because a database transaction is still in progress. The
danielebarchiesi@0 506 * transaction is not finalized until the save operation is entirely completed
danielebarchiesi@0 507 * and node_save() goes out of scope. You should not rely on data in the
danielebarchiesi@0 508 * database at this time as it is not updated yet. You should also note that any
danielebarchiesi@0 509 * write/update database queries executed from this hook are also not committed
danielebarchiesi@0 510 * immediately. Check node_save() and db_transaction() for more info.
danielebarchiesi@0 511 *
danielebarchiesi@0 512 * @param $node
danielebarchiesi@0 513 * The node that is being created.
danielebarchiesi@0 514 *
danielebarchiesi@0 515 * @ingroup node_api_hooks
danielebarchiesi@0 516 */
danielebarchiesi@0 517 function hook_node_insert($node) {
danielebarchiesi@0 518 db_insert('mytable')
danielebarchiesi@0 519 ->fields(array(
danielebarchiesi@0 520 'nid' => $node->nid,
danielebarchiesi@0 521 'extra' => $node->extra,
danielebarchiesi@0 522 ))
danielebarchiesi@0 523 ->execute();
danielebarchiesi@0 524 }
danielebarchiesi@0 525
danielebarchiesi@0 526 /**
danielebarchiesi@0 527 * Act on arbitrary nodes being loaded from the database.
danielebarchiesi@0 528 *
danielebarchiesi@0 529 * This hook should be used to add information that is not in the node or node
danielebarchiesi@0 530 * revisions table, not to replace information that is in these tables (which
danielebarchiesi@0 531 * could interfere with the entity cache). For performance reasons, information
danielebarchiesi@0 532 * for all available nodes should be loaded in a single query where possible.
danielebarchiesi@0 533 *
danielebarchiesi@0 534 * This hook is invoked during node loading, which is handled by entity_load(),
danielebarchiesi@0 535 * via classes NodeController and DrupalDefaultEntityController. After the node
danielebarchiesi@0 536 * information is read from the database or the entity cache, hook_load() is
danielebarchiesi@0 537 * invoked on the node's content type module, then field_attach_load_revision()
danielebarchiesi@0 538 * or field_attach_load() is called, then hook_entity_load() is invoked on all
danielebarchiesi@0 539 * implementing modules, and finally hook_node_load() is invoked on all
danielebarchiesi@0 540 * implementing modules.
danielebarchiesi@0 541 *
danielebarchiesi@0 542 * @param $nodes
danielebarchiesi@0 543 * An array of the nodes being loaded, keyed by nid.
danielebarchiesi@0 544 * @param $types
danielebarchiesi@0 545 * An array containing the node types present in $nodes. Allows for an early
danielebarchiesi@0 546 * return for modules that only support certain node types. However, if your
danielebarchiesi@0 547 * module defines a content type, you can use hook_load() to respond to
danielebarchiesi@0 548 * loading of just that content type.
danielebarchiesi@0 549 *
danielebarchiesi@0 550 * For a detailed usage example, see nodeapi_example.module.
danielebarchiesi@0 551 *
danielebarchiesi@0 552 * @ingroup node_api_hooks
danielebarchiesi@0 553 */
danielebarchiesi@0 554 function hook_node_load($nodes, $types) {
danielebarchiesi@0 555 // Decide whether any of $types are relevant to our purposes.
danielebarchiesi@0 556 if (count(array_intersect($types_we_want_to_process, $types))) {
danielebarchiesi@0 557 // Gather our extra data for each of these nodes.
danielebarchiesi@0 558 $result = db_query('SELECT nid, foo FROM {mytable} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)));
danielebarchiesi@0 559 // Add our extra data to the node objects.
danielebarchiesi@0 560 foreach ($result as $record) {
danielebarchiesi@0 561 $nodes[$record->nid]->foo = $record->foo;
danielebarchiesi@0 562 }
danielebarchiesi@0 563 }
danielebarchiesi@0 564 }
danielebarchiesi@0 565
danielebarchiesi@0 566 /**
danielebarchiesi@0 567 * Control access to a node.
danielebarchiesi@0 568 *
danielebarchiesi@0 569 * Modules may implement this hook if they want to have a say in whether or not
danielebarchiesi@0 570 * a given user has access to perform a given operation on a node.
danielebarchiesi@0 571 *
danielebarchiesi@0 572 * The administrative account (user ID #1) always passes any access check, so
danielebarchiesi@0 573 * this hook is not called in that case. Users with the "bypass node access"
danielebarchiesi@0 574 * permission may always view and edit content through the administrative
danielebarchiesi@0 575 * interface.
danielebarchiesi@0 576 *
danielebarchiesi@0 577 * Note that not all modules will want to influence access on all node types. If
danielebarchiesi@0 578 * your module does not want to actively grant or block access, return
danielebarchiesi@0 579 * NODE_ACCESS_IGNORE or simply return nothing. Blindly returning FALSE will
danielebarchiesi@0 580 * break other node access modules.
danielebarchiesi@0 581 *
danielebarchiesi@0 582 * Also note that this function isn't called for node listings (e.g., RSS feeds,
danielebarchiesi@0 583 * the default home page at path 'node', a recent content block, etc.) See
danielebarchiesi@0 584 * @link node_access Node access rights @endlink for a full explanation.
danielebarchiesi@0 585 *
danielebarchiesi@0 586 * @param $node
danielebarchiesi@0 587 * Either a node object or the machine name of the content type on which to
danielebarchiesi@0 588 * perform the access check.
danielebarchiesi@0 589 * @param $op
danielebarchiesi@0 590 * The operation to be performed. Possible values:
danielebarchiesi@0 591 * - "create"
danielebarchiesi@0 592 * - "delete"
danielebarchiesi@0 593 * - "update"
danielebarchiesi@0 594 * - "view"
danielebarchiesi@0 595 * @param $account
danielebarchiesi@0 596 * The user object to perform the access check operation on.
danielebarchiesi@0 597 *
danielebarchiesi@0 598 * @return
danielebarchiesi@0 599 * - NODE_ACCESS_ALLOW: if the operation is to be allowed.
danielebarchiesi@0 600 * - NODE_ACCESS_DENY: if the operation is to be denied.
danielebarchiesi@0 601 * - NODE_ACCESS_IGNORE: to not affect this operation at all.
danielebarchiesi@0 602 *
danielebarchiesi@0 603 * @ingroup node_access
danielebarchiesi@0 604 */
danielebarchiesi@0 605 function hook_node_access($node, $op, $account) {
danielebarchiesi@0 606 $type = is_string($node) ? $node : $node->type;
danielebarchiesi@0 607
danielebarchiesi@0 608 if (in_array($type, node_permissions_get_configured_types())) {
danielebarchiesi@0 609 if ($op == 'create' && user_access('create ' . $type . ' content', $account)) {
danielebarchiesi@0 610 return NODE_ACCESS_ALLOW;
danielebarchiesi@0 611 }
danielebarchiesi@0 612
danielebarchiesi@0 613 if ($op == 'update') {
danielebarchiesi@0 614 if (user_access('edit any ' . $type . ' content', $account) || (user_access('edit own ' . $type . ' content', $account) && ($account->uid == $node->uid))) {
danielebarchiesi@0 615 return NODE_ACCESS_ALLOW;
danielebarchiesi@0 616 }
danielebarchiesi@0 617 }
danielebarchiesi@0 618
danielebarchiesi@0 619 if ($op == 'delete') {
danielebarchiesi@0 620 if (user_access('delete any ' . $type . ' content', $account) || (user_access('delete own ' . $type . ' content', $account) && ($account->uid == $node->uid))) {
danielebarchiesi@0 621 return NODE_ACCESS_ALLOW;
danielebarchiesi@0 622 }
danielebarchiesi@0 623 }
danielebarchiesi@0 624 }
danielebarchiesi@0 625
danielebarchiesi@0 626 // Returning nothing from this function would have the same effect.
danielebarchiesi@0 627 return NODE_ACCESS_IGNORE;
danielebarchiesi@0 628 }
danielebarchiesi@0 629
danielebarchiesi@0 630
danielebarchiesi@0 631 /**
danielebarchiesi@0 632 * Act on a node object about to be shown on the add/edit form.
danielebarchiesi@0 633 *
danielebarchiesi@0 634 * This hook is invoked from node_object_prepare() after the type-specific
danielebarchiesi@0 635 * hook_prepare() is invoked.
danielebarchiesi@0 636 *
danielebarchiesi@0 637 * @param $node
danielebarchiesi@0 638 * The node that is about to be shown on the add/edit form.
danielebarchiesi@0 639 *
danielebarchiesi@0 640 * @ingroup node_api_hooks
danielebarchiesi@0 641 */
danielebarchiesi@0 642 function hook_node_prepare($node) {
danielebarchiesi@0 643 if (!isset($node->comment)) {
danielebarchiesi@0 644 $node->comment = variable_get("comment_$node->type", COMMENT_NODE_OPEN);
danielebarchiesi@0 645 }
danielebarchiesi@0 646 }
danielebarchiesi@0 647
danielebarchiesi@0 648 /**
danielebarchiesi@0 649 * Act on a node being displayed as a search result.
danielebarchiesi@0 650 *
danielebarchiesi@0 651 * This hook is invoked from node_search_execute(), after node_load() and
danielebarchiesi@0 652 * node_view() have been called.
danielebarchiesi@0 653 *
danielebarchiesi@0 654 * @param $node
danielebarchiesi@0 655 * The node being displayed in a search result.
danielebarchiesi@0 656 *
danielebarchiesi@0 657 * @return array
danielebarchiesi@0 658 * Extra information to be displayed with search result. This information
danielebarchiesi@0 659 * should be presented as an associative array. It will be concatenated with
danielebarchiesi@0 660 * the post information (last updated, author) in the default search result
danielebarchiesi@0 661 * theming.
danielebarchiesi@0 662 *
danielebarchiesi@0 663 * @see template_preprocess_search_result()
danielebarchiesi@0 664 * @see search-result.tpl.php
danielebarchiesi@0 665 *
danielebarchiesi@0 666 * @ingroup node_api_hooks
danielebarchiesi@0 667 */
danielebarchiesi@0 668 function hook_node_search_result($node) {
danielebarchiesi@0 669 $comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array('nid' => $node->nid))->fetchField();
danielebarchiesi@0 670 return array('comment' => format_plural($comments, '1 comment', '@count comments'));
danielebarchiesi@0 671 }
danielebarchiesi@0 672
danielebarchiesi@0 673 /**
danielebarchiesi@0 674 * Act on a node being inserted or updated.
danielebarchiesi@0 675 *
danielebarchiesi@0 676 * This hook is invoked from node_save() before the node is saved to the
danielebarchiesi@0 677 * database.
danielebarchiesi@0 678 *
danielebarchiesi@0 679 * @param $node
danielebarchiesi@0 680 * The node that is being inserted or updated.
danielebarchiesi@0 681 *
danielebarchiesi@0 682 * @ingroup node_api_hooks
danielebarchiesi@0 683 */
danielebarchiesi@0 684 function hook_node_presave($node) {
danielebarchiesi@0 685 if ($node->nid && $node->moderate) {
danielebarchiesi@0 686 // Reset votes when node is updated:
danielebarchiesi@0 687 $node->score = 0;
danielebarchiesi@0 688 $node->users = '';
danielebarchiesi@0 689 $node->votes = 0;
danielebarchiesi@0 690 }
danielebarchiesi@0 691 }
danielebarchiesi@0 692
danielebarchiesi@0 693 /**
danielebarchiesi@0 694 * Respond to updates to a node.
danielebarchiesi@0 695 *
danielebarchiesi@0 696 * This hook is invoked from node_save() after the database query that will
danielebarchiesi@0 697 * update node in the node table is scheduled for execution, after the
danielebarchiesi@0 698 * type-specific hook_update() is invoked, and after field_attach_update() is
danielebarchiesi@0 699 * called.
danielebarchiesi@0 700 *
danielebarchiesi@0 701 * Note that when this hook is invoked, the changes have not yet been written to
danielebarchiesi@0 702 * the database, because a database transaction is still in progress. The
danielebarchiesi@0 703 * transaction is not finalized until the save operation is entirely completed
danielebarchiesi@0 704 * and node_save() goes out of scope. You should not rely on data in the
danielebarchiesi@0 705 * database at this time as it is not updated yet. You should also note that any
danielebarchiesi@0 706 * write/update database queries executed from this hook are also not committed
danielebarchiesi@0 707 * immediately. Check node_save() and db_transaction() for more info.
danielebarchiesi@0 708 *
danielebarchiesi@0 709 * @param $node
danielebarchiesi@0 710 * The node that is being updated.
danielebarchiesi@0 711 *
danielebarchiesi@0 712 * @ingroup node_api_hooks
danielebarchiesi@0 713 */
danielebarchiesi@0 714 function hook_node_update($node) {
danielebarchiesi@0 715 db_update('mytable')
danielebarchiesi@0 716 ->fields(array('extra' => $node->extra))
danielebarchiesi@0 717 ->condition('nid', $node->nid)
danielebarchiesi@0 718 ->execute();
danielebarchiesi@0 719 }
danielebarchiesi@0 720
danielebarchiesi@0 721 /**
danielebarchiesi@0 722 * Act on a node being indexed for searching.
danielebarchiesi@0 723 *
danielebarchiesi@0 724 * This hook is invoked during search indexing, after node_load(), and after the
danielebarchiesi@0 725 * result of node_view() is added as $node->rendered to the node object.
danielebarchiesi@0 726 *
danielebarchiesi@0 727 * @param $node
danielebarchiesi@0 728 * The node being indexed.
danielebarchiesi@0 729 *
danielebarchiesi@0 730 * @return string
danielebarchiesi@0 731 * Additional node information to be indexed.
danielebarchiesi@0 732 *
danielebarchiesi@0 733 * @ingroup node_api_hooks
danielebarchiesi@0 734 */
danielebarchiesi@0 735 function hook_node_update_index($node) {
danielebarchiesi@0 736 $text = '';
danielebarchiesi@0 737 $comments = db_query('SELECT subject, comment, format FROM {comment} WHERE nid = :nid AND status = :status', array(':nid' => $node->nid, ':status' => COMMENT_PUBLISHED));
danielebarchiesi@0 738 foreach ($comments as $comment) {
danielebarchiesi@0 739 $text .= '<h2>' . check_plain($comment->subject) . '</h2>' . check_markup($comment->comment, $comment->format, '', TRUE);
danielebarchiesi@0 740 }
danielebarchiesi@0 741 return $text;
danielebarchiesi@0 742 }
danielebarchiesi@0 743
danielebarchiesi@0 744 /**
danielebarchiesi@0 745 * Perform node validation before a node is created or updated.
danielebarchiesi@0 746 *
danielebarchiesi@0 747 * This hook is invoked from node_validate(), after a user has has finished
danielebarchiesi@0 748 * editing the node and is previewing or submitting it. It is invoked at the
danielebarchiesi@0 749 * end of all the standard validation steps, and after the type-specific
danielebarchiesi@0 750 * hook_validate() is invoked.
danielebarchiesi@0 751 *
danielebarchiesi@0 752 * To indicate a validation error, use form_set_error().
danielebarchiesi@0 753 *
danielebarchiesi@0 754 * Note: Changes made to the $node object within your hook implementation will
danielebarchiesi@0 755 * have no effect. The preferred method to change a node's content is to use
danielebarchiesi@0 756 * hook_node_presave() instead. If it is really necessary to change the node at
danielebarchiesi@0 757 * the validate stage, you can use form_set_value().
danielebarchiesi@0 758 *
danielebarchiesi@0 759 * @param $node
danielebarchiesi@0 760 * The node being validated.
danielebarchiesi@0 761 * @param $form
danielebarchiesi@0 762 * The form being used to edit the node.
danielebarchiesi@0 763 * @param $form_state
danielebarchiesi@0 764 * The form state array.
danielebarchiesi@0 765 *
danielebarchiesi@0 766 * @ingroup node_api_hooks
danielebarchiesi@0 767 */
danielebarchiesi@0 768 function hook_node_validate($node, $form, &$form_state) {
danielebarchiesi@0 769 if (isset($node->end) && isset($node->start)) {
danielebarchiesi@0 770 if ($node->start > $node->end) {
danielebarchiesi@0 771 form_set_error('time', t('An event may not end before it starts.'));
danielebarchiesi@0 772 }
danielebarchiesi@0 773 }
danielebarchiesi@0 774 }
danielebarchiesi@0 775
danielebarchiesi@0 776 /**
danielebarchiesi@0 777 * Act on a node after validated form values have been copied to it.
danielebarchiesi@0 778 *
danielebarchiesi@0 779 * This hook is invoked when a node form is submitted with either the "Save" or
danielebarchiesi@0 780 * "Preview" button, after form values have been copied to the form state's node
danielebarchiesi@0 781 * object, but before the node is saved or previewed. It is a chance for modules
danielebarchiesi@0 782 * to adjust the node's properties from what they are simply after a copy from
danielebarchiesi@0 783 * $form_state['values']. This hook is intended for adjusting non-field-related
danielebarchiesi@0 784 * properties. See hook_field_attach_submit() for customizing field-related
danielebarchiesi@0 785 * properties.
danielebarchiesi@0 786 *
danielebarchiesi@0 787 * @param $node
danielebarchiesi@0 788 * The node object being updated in response to a form submission.
danielebarchiesi@0 789 * @param $form
danielebarchiesi@0 790 * The form being used to edit the node.
danielebarchiesi@0 791 * @param $form_state
danielebarchiesi@0 792 * The form state array.
danielebarchiesi@0 793 *
danielebarchiesi@0 794 * @ingroup node_api_hooks
danielebarchiesi@0 795 */
danielebarchiesi@0 796 function hook_node_submit($node, $form, &$form_state) {
danielebarchiesi@0 797 // Decompose the selected menu parent option into 'menu_name' and 'plid', if
danielebarchiesi@0 798 // the form used the default parent selection widget.
danielebarchiesi@0 799 if (!empty($form_state['values']['menu']['parent'])) {
danielebarchiesi@0 800 list($node->menu['menu_name'], $node->menu['plid']) = explode(':', $form_state['values']['menu']['parent']);
danielebarchiesi@0 801 }
danielebarchiesi@0 802 }
danielebarchiesi@0 803
danielebarchiesi@0 804 /**
danielebarchiesi@0 805 * Act on a node that is being assembled before rendering.
danielebarchiesi@0 806 *
danielebarchiesi@0 807 * The module may add elements to $node->content prior to rendering. This hook
danielebarchiesi@0 808 * will be called after hook_view(). The structure of $node->content is a
danielebarchiesi@0 809 * renderable array as expected by drupal_render().
danielebarchiesi@0 810 *
danielebarchiesi@0 811 * When $view_mode is 'rss', modules can also add extra RSS elements and
danielebarchiesi@0 812 * namespaces to $node->rss_elements and $node->rss_namespaces respectively for
danielebarchiesi@0 813 * the RSS item generated for this node.
danielebarchiesi@0 814 * For details on how this is used, see node_feed().
danielebarchiesi@0 815 *
danielebarchiesi@0 816 * @see blog_node_view()
danielebarchiesi@0 817 * @see forum_node_view()
danielebarchiesi@0 818 * @see comment_node_view()
danielebarchiesi@0 819 *
danielebarchiesi@0 820 * @param $node
danielebarchiesi@0 821 * The node that is being assembled for rendering.
danielebarchiesi@0 822 * @param $view_mode
danielebarchiesi@0 823 * The $view_mode parameter from node_view().
danielebarchiesi@0 824 * @param $langcode
danielebarchiesi@0 825 * The language code used for rendering.
danielebarchiesi@0 826 *
danielebarchiesi@0 827 * @see hook_entity_view()
danielebarchiesi@0 828 *
danielebarchiesi@0 829 * @ingroup node_api_hooks
danielebarchiesi@0 830 */
danielebarchiesi@0 831 function hook_node_view($node, $view_mode, $langcode) {
danielebarchiesi@0 832 $node->content['my_additional_field'] = array(
danielebarchiesi@0 833 '#markup' => $additional_field,
danielebarchiesi@0 834 '#weight' => 10,
danielebarchiesi@0 835 '#theme' => 'mymodule_my_additional_field',
danielebarchiesi@0 836 );
danielebarchiesi@0 837 }
danielebarchiesi@0 838
danielebarchiesi@0 839 /**
danielebarchiesi@0 840 * Alter the results of node_view().
danielebarchiesi@0 841 *
danielebarchiesi@0 842 * This hook is called after the content has been assembled in a structured
danielebarchiesi@0 843 * array and may be used for doing processing which requires that the complete
danielebarchiesi@0 844 * node content structure has been built.
danielebarchiesi@0 845 *
danielebarchiesi@0 846 * If the module wishes to act on the rendered HTML of the node rather than the
danielebarchiesi@0 847 * structured content array, it may use this hook to add a #post_render
danielebarchiesi@0 848 * callback. Alternatively, it could also implement hook_preprocess_node(). See
danielebarchiesi@0 849 * drupal_render() and theme() documentation respectively for details.
danielebarchiesi@0 850 *
danielebarchiesi@0 851 * @param $build
danielebarchiesi@0 852 * A renderable array representing the node content.
danielebarchiesi@0 853 *
danielebarchiesi@0 854 * @see node_view()
danielebarchiesi@0 855 * @see hook_entity_view_alter()
danielebarchiesi@0 856 *
danielebarchiesi@0 857 * @ingroup node_api_hooks
danielebarchiesi@0 858 */
danielebarchiesi@0 859 function hook_node_view_alter(&$build) {
danielebarchiesi@0 860 if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
danielebarchiesi@0 861 // Change its weight.
danielebarchiesi@0 862 $build['an_additional_field']['#weight'] = -10;
danielebarchiesi@0 863 }
danielebarchiesi@0 864
danielebarchiesi@0 865 // Add a #post_render callback to act on the rendered HTML of the node.
danielebarchiesi@0 866 $build['#post_render'][] = 'my_module_node_post_render';
danielebarchiesi@0 867 }
danielebarchiesi@0 868
danielebarchiesi@0 869 /**
danielebarchiesi@0 870 * Define module-provided node types.
danielebarchiesi@0 871 *
danielebarchiesi@0 872 * This hook allows a module to define one or more of its own node types. For
danielebarchiesi@0 873 * example, the blog module uses it to define a blog node-type named "Blog
danielebarchiesi@0 874 * entry." The name and attributes of each desired node type are specified in an
danielebarchiesi@0 875 * array returned by the hook.
danielebarchiesi@0 876 *
danielebarchiesi@0 877 * Only module-provided node types should be defined through this hook. User-
danielebarchiesi@0 878 * provided (or 'custom') node types should be defined only in the 'node_type'
danielebarchiesi@0 879 * database table, and should be maintained by using the node_type_save() and
danielebarchiesi@0 880 * node_type_delete() functions.
danielebarchiesi@0 881 *
danielebarchiesi@0 882 * @return
danielebarchiesi@0 883 * An array of information defining the module's node types. The array
danielebarchiesi@0 884 * contains a sub-array for each node type, with the machine-readable type
danielebarchiesi@0 885 * name as the key. Each sub-array has up to 10 attributes. Possible
danielebarchiesi@0 886 * attributes:
danielebarchiesi@0 887 * - name: (required) The human-readable name of the node type.
danielebarchiesi@0 888 * - base: (required) The base string used to construct callbacks
danielebarchiesi@0 889 * corresponding to this node type (for example, if base is defined as
danielebarchiesi@0 890 * example_foo, then example_foo_insert will be called when inserting a node
danielebarchiesi@0 891 * of that type). This string is usually the name of the module, but not
danielebarchiesi@0 892 * always.
danielebarchiesi@0 893 * - description: (required) A brief description of the node type.
danielebarchiesi@0 894 * - help: (optional) Help information shown to the user when creating a node
danielebarchiesi@0 895 * of this type.
danielebarchiesi@0 896 * - has_title: (optional) A Boolean indicating whether or not this node type
danielebarchiesi@0 897 * has a title field.
danielebarchiesi@0 898 * - title_label: (optional) The label for the title field of this content
danielebarchiesi@0 899 * type.
danielebarchiesi@0 900 * - locked: (optional) A Boolean indicating whether the administrator can
danielebarchiesi@0 901 * change the machine name of this type. FALSE = changeable (not locked),
danielebarchiesi@0 902 * TRUE = unchangeable (locked).
danielebarchiesi@0 903 *
danielebarchiesi@0 904 * The machine name of a node type should contain only letters, numbers, and
danielebarchiesi@0 905 * underscores. Underscores will be converted into hyphens for the purpose of
danielebarchiesi@0 906 * constructing URLs.
danielebarchiesi@0 907 *
danielebarchiesi@0 908 * All attributes of a node type that are defined through this hook (except for
danielebarchiesi@0 909 * 'locked') can be edited by a site administrator. This includes the
danielebarchiesi@0 910 * machine-readable name of a node type, if 'locked' is set to FALSE.
danielebarchiesi@0 911 *
danielebarchiesi@0 912 * @ingroup node_api_hooks
danielebarchiesi@0 913 */
danielebarchiesi@0 914 function hook_node_info() {
danielebarchiesi@0 915 return array(
danielebarchiesi@0 916 'blog' => array(
danielebarchiesi@0 917 'name' => t('Blog entry'),
danielebarchiesi@0 918 'base' => 'blog',
danielebarchiesi@0 919 'description' => t('Use for multi-user blogs. Every user gets a personal blog.'),
danielebarchiesi@0 920 )
danielebarchiesi@0 921 );
danielebarchiesi@0 922 }
danielebarchiesi@0 923
danielebarchiesi@0 924 /**
danielebarchiesi@0 925 * Provide additional methods of scoring for core search results for nodes.
danielebarchiesi@0 926 *
danielebarchiesi@0 927 * A node's search score is used to rank it among other nodes matched by the
danielebarchiesi@0 928 * search, with the highest-ranked nodes appearing first in the search listing.
danielebarchiesi@0 929 *
danielebarchiesi@0 930 * For example, a module allowing users to vote on content could expose an
danielebarchiesi@0 931 * option to allow search results' rankings to be influenced by the average
danielebarchiesi@0 932 * voting score of a node.
danielebarchiesi@0 933 *
danielebarchiesi@0 934 * All scoring mechanisms are provided as options to site administrators, and
danielebarchiesi@0 935 * may be tweaked based on individual sites or disabled altogether if they do
danielebarchiesi@0 936 * not make sense. Individual scoring mechanisms, if enabled, are assigned a
danielebarchiesi@0 937 * weight from 1 to 10. The weight represents the factor of magnification of
danielebarchiesi@0 938 * the ranking mechanism, with higher-weighted ranking mechanisms having more
danielebarchiesi@0 939 * influence. In order for the weight system to work, each scoring mechanism
danielebarchiesi@0 940 * must return a value between 0 and 1 for every node. That value is then
danielebarchiesi@0 941 * multiplied by the administrator-assigned weight for the ranking mechanism,
danielebarchiesi@0 942 * and then the weighted scores from all ranking mechanisms are added, which
danielebarchiesi@0 943 * brings about the same result as a weighted average.
danielebarchiesi@0 944 *
danielebarchiesi@0 945 * @return
danielebarchiesi@0 946 * An associative array of ranking data. The keys should be strings,
danielebarchiesi@0 947 * corresponding to the internal name of the ranking mechanism, such as
danielebarchiesi@0 948 * 'recent', or 'comments'. The values should be arrays themselves, with the
danielebarchiesi@0 949 * following keys available:
danielebarchiesi@0 950 * - title: (required) The human readable name of the ranking mechanism.
danielebarchiesi@0 951 * - join: (optional) The part of a query string to join to any additional
danielebarchiesi@0 952 * necessary table. This is not necessary if the table required is already
danielebarchiesi@0 953 * joined to by the base query, such as for the {node} table. Other tables
danielebarchiesi@0 954 * should use the full table name as an alias to avoid naming collisions.
danielebarchiesi@0 955 * - score: (required) The part of a query string to calculate the score for
danielebarchiesi@0 956 * the ranking mechanism based on values in the database. This does not need
danielebarchiesi@0 957 * to be wrapped in parentheses, as it will be done automatically; it also
danielebarchiesi@0 958 * does not need to take the weighted system into account, as it will be
danielebarchiesi@0 959 * done automatically. It does, however, need to calculate a decimal between
danielebarchiesi@0 960 * 0 and 1; be careful not to cast the entire score to an integer by
danielebarchiesi@0 961 * inadvertently introducing a variable argument.
danielebarchiesi@0 962 * - arguments: (optional) If any arguments are required for the score, they
danielebarchiesi@0 963 * can be specified in an array here.
danielebarchiesi@0 964 *
danielebarchiesi@0 965 * @ingroup node_api_hooks
danielebarchiesi@0 966 */
danielebarchiesi@0 967 function hook_ranking() {
danielebarchiesi@0 968 // If voting is disabled, we can avoid returning the array, no hard feelings.
danielebarchiesi@0 969 if (variable_get('vote_node_enabled', TRUE)) {
danielebarchiesi@0 970 return array(
danielebarchiesi@0 971 'vote_average' => array(
danielebarchiesi@0 972 'title' => t('Average vote'),
danielebarchiesi@0 973 // Note that we use i.sid, the search index's search item id, rather than
danielebarchiesi@0 974 // n.nid.
danielebarchiesi@0 975 'join' => 'LEFT JOIN {vote_node_data} vote_node_data ON vote_node_data.nid = i.sid',
danielebarchiesi@0 976 // The highest possible score should be 1, and the lowest possible score,
danielebarchiesi@0 977 // always 0, should be 0.
danielebarchiesi@0 978 'score' => 'vote_node_data.average / CAST(%f AS DECIMAL)',
danielebarchiesi@0 979 // Pass in the highest possible voting score as a decimal argument.
danielebarchiesi@0 980 'arguments' => array(variable_get('vote_score_max', 5)),
danielebarchiesi@0 981 ),
danielebarchiesi@0 982 );
danielebarchiesi@0 983 }
danielebarchiesi@0 984 }
danielebarchiesi@0 985
danielebarchiesi@0 986
danielebarchiesi@0 987 /**
danielebarchiesi@0 988 * Respond to node type creation.
danielebarchiesi@0 989 *
danielebarchiesi@0 990 * This hook is invoked from node_type_save() after the node type is added to
danielebarchiesi@0 991 * the database.
danielebarchiesi@0 992 *
danielebarchiesi@0 993 * @param $info
danielebarchiesi@0 994 * The node type object that is being created.
danielebarchiesi@0 995 */
danielebarchiesi@0 996 function hook_node_type_insert($info) {
danielebarchiesi@0 997 drupal_set_message(t('You have just created a content type with a machine name %type.', array('%type' => $info->type)));
danielebarchiesi@0 998 }
danielebarchiesi@0 999
danielebarchiesi@0 1000 /**
danielebarchiesi@0 1001 * Respond to node type updates.
danielebarchiesi@0 1002 *
danielebarchiesi@0 1003 * This hook is invoked from node_type_save() after the node type is updated in
danielebarchiesi@0 1004 * the database.
danielebarchiesi@0 1005 *
danielebarchiesi@0 1006 * @param $info
danielebarchiesi@0 1007 * The node type object that is being updated.
danielebarchiesi@0 1008 */
danielebarchiesi@0 1009 function hook_node_type_update($info) {
danielebarchiesi@0 1010 if (!empty($info->old_type) && $info->old_type != $info->type) {
danielebarchiesi@0 1011 $setting = variable_get('comment_' . $info->old_type, COMMENT_NODE_OPEN);
danielebarchiesi@0 1012 variable_del('comment_' . $info->old_type);
danielebarchiesi@0 1013 variable_set('comment_' . $info->type, $setting);
danielebarchiesi@0 1014 }
danielebarchiesi@0 1015 }
danielebarchiesi@0 1016
danielebarchiesi@0 1017 /**
danielebarchiesi@0 1018 * Respond to node type deletion.
danielebarchiesi@0 1019 *
danielebarchiesi@0 1020 * This hook is invoked from node_type_delete() after the node type is removed
danielebarchiesi@0 1021 * from the database.
danielebarchiesi@0 1022 *
danielebarchiesi@0 1023 * @param $info
danielebarchiesi@0 1024 * The node type object that is being deleted.
danielebarchiesi@0 1025 */
danielebarchiesi@0 1026 function hook_node_type_delete($info) {
danielebarchiesi@0 1027 variable_del('comment_' . $info->type);
danielebarchiesi@0 1028 }
danielebarchiesi@0 1029
danielebarchiesi@0 1030 /**
danielebarchiesi@0 1031 * Respond to node deletion.
danielebarchiesi@0 1032 *
danielebarchiesi@0 1033 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1034 * (use hook_node_delete() to respond to all node deletions).
danielebarchiesi@0 1035 *
danielebarchiesi@0 1036 * This hook is invoked from node_delete_multiple() after the node has been
danielebarchiesi@0 1037 * removed from the node table in the database, before hook_node_delete() is
danielebarchiesi@0 1038 * invoked, and before field_attach_delete() is called.
danielebarchiesi@0 1039 *
danielebarchiesi@0 1040 * @param $node
danielebarchiesi@0 1041 * The node that is being deleted.
danielebarchiesi@0 1042 *
danielebarchiesi@0 1043 * @ingroup node_api_hooks
danielebarchiesi@0 1044 */
danielebarchiesi@0 1045 function hook_delete($node) {
danielebarchiesi@0 1046 db_delete('mytable')
danielebarchiesi@0 1047 ->condition('nid', $node->nid)
danielebarchiesi@0 1048 ->execute();
danielebarchiesi@0 1049 }
danielebarchiesi@0 1050
danielebarchiesi@0 1051 /**
danielebarchiesi@0 1052 * Act on a node object about to be shown on the add/edit form.
danielebarchiesi@0 1053 *
danielebarchiesi@0 1054 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1055 * (use hook_node_prepare() to act on all node preparations).
danielebarchiesi@0 1056 *
danielebarchiesi@0 1057 * This hook is invoked from node_object_prepare() before the general
danielebarchiesi@0 1058 * hook_node_prepare() is invoked.
danielebarchiesi@0 1059 *
danielebarchiesi@0 1060 * @param $node
danielebarchiesi@0 1061 * The node that is about to be shown on the add/edit form.
danielebarchiesi@0 1062 *
danielebarchiesi@0 1063 * @ingroup node_api_hooks
danielebarchiesi@0 1064 */
danielebarchiesi@0 1065 function hook_prepare($node) {
danielebarchiesi@0 1066 if ($file = file_check_upload($field_name)) {
danielebarchiesi@0 1067 $file = file_save_upload($field_name, _image_filename($file->filename, NULL, TRUE));
danielebarchiesi@0 1068 if ($file) {
danielebarchiesi@0 1069 if (!image_get_info($file->uri)) {
danielebarchiesi@0 1070 form_set_error($field_name, t('Uploaded file is not a valid image'));
danielebarchiesi@0 1071 return;
danielebarchiesi@0 1072 }
danielebarchiesi@0 1073 }
danielebarchiesi@0 1074 else {
danielebarchiesi@0 1075 return;
danielebarchiesi@0 1076 }
danielebarchiesi@0 1077 $node->images['_original'] = $file->uri;
danielebarchiesi@0 1078 _image_build_derivatives($node, TRUE);
danielebarchiesi@0 1079 $node->new_file = TRUE;
danielebarchiesi@0 1080 }
danielebarchiesi@0 1081 }
danielebarchiesi@0 1082
danielebarchiesi@0 1083 /**
danielebarchiesi@0 1084 * Display a node editing form.
danielebarchiesi@0 1085 *
danielebarchiesi@0 1086 * This hook, implemented by node modules, is called to retrieve the form
danielebarchiesi@0 1087 * that is displayed to create or edit a node. This form is displayed at path
danielebarchiesi@0 1088 * node/add/[node type] or node/[node ID]/edit.
danielebarchiesi@0 1089 *
danielebarchiesi@0 1090 * The submit and preview buttons, administrative and display controls, and
danielebarchiesi@0 1091 * sections added by other modules (such as path settings, menu settings,
danielebarchiesi@0 1092 * comment settings, and fields managed by the Field UI module) are
danielebarchiesi@0 1093 * displayed automatically by the node module. This hook just needs to
danielebarchiesi@0 1094 * return the node title and form editing fields specific to the node type.
danielebarchiesi@0 1095 *
danielebarchiesi@0 1096 * @param $node
danielebarchiesi@0 1097 * The node being added or edited.
danielebarchiesi@0 1098 * @param $form_state
danielebarchiesi@0 1099 * The form state array.
danielebarchiesi@0 1100 *
danielebarchiesi@0 1101 * @return
danielebarchiesi@0 1102 * An array containing the title and any custom form elements to be displayed
danielebarchiesi@0 1103 * in the node editing form.
danielebarchiesi@0 1104 *
danielebarchiesi@0 1105 * @ingroup node_api_hooks
danielebarchiesi@0 1106 */
danielebarchiesi@0 1107 function hook_form($node, &$form_state) {
danielebarchiesi@0 1108 $type = node_type_get_type($node);
danielebarchiesi@0 1109
danielebarchiesi@0 1110 $form['title'] = array(
danielebarchiesi@0 1111 '#type' => 'textfield',
danielebarchiesi@0 1112 '#title' => check_plain($type->title_label),
danielebarchiesi@0 1113 '#default_value' => !empty($node->title) ? $node->title : '',
danielebarchiesi@0 1114 '#required' => TRUE, '#weight' => -5
danielebarchiesi@0 1115 );
danielebarchiesi@0 1116
danielebarchiesi@0 1117 $form['field1'] = array(
danielebarchiesi@0 1118 '#type' => 'textfield',
danielebarchiesi@0 1119 '#title' => t('Custom field'),
danielebarchiesi@0 1120 '#default_value' => $node->field1,
danielebarchiesi@0 1121 '#maxlength' => 127,
danielebarchiesi@0 1122 );
danielebarchiesi@0 1123 $form['selectbox'] = array(
danielebarchiesi@0 1124 '#type' => 'select',
danielebarchiesi@0 1125 '#title' => t('Select box'),
danielebarchiesi@0 1126 '#default_value' => $node->selectbox,
danielebarchiesi@0 1127 '#options' => array(
danielebarchiesi@0 1128 1 => 'Option A',
danielebarchiesi@0 1129 2 => 'Option B',
danielebarchiesi@0 1130 3 => 'Option C',
danielebarchiesi@0 1131 ),
danielebarchiesi@0 1132 '#description' => t('Choose an option.'),
danielebarchiesi@0 1133 );
danielebarchiesi@0 1134
danielebarchiesi@0 1135 return $form;
danielebarchiesi@0 1136 }
danielebarchiesi@0 1137
danielebarchiesi@0 1138 /**
danielebarchiesi@0 1139 * Respond to creation of a new node.
danielebarchiesi@0 1140 *
danielebarchiesi@0 1141 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1142 * (use hook_node_insert() to act on all node insertions).
danielebarchiesi@0 1143 *
danielebarchiesi@0 1144 * This hook is invoked from node_save() after the node is inserted into the
danielebarchiesi@0 1145 * node table in the database, before field_attach_insert() is called, and
danielebarchiesi@0 1146 * before hook_node_insert() is invoked.
danielebarchiesi@0 1147 *
danielebarchiesi@0 1148 * @param $node
danielebarchiesi@0 1149 * The node that is being created.
danielebarchiesi@0 1150 *
danielebarchiesi@0 1151 * @ingroup node_api_hooks
danielebarchiesi@0 1152 */
danielebarchiesi@0 1153 function hook_insert($node) {
danielebarchiesi@0 1154 db_insert('mytable')
danielebarchiesi@0 1155 ->fields(array(
danielebarchiesi@0 1156 'nid' => $node->nid,
danielebarchiesi@0 1157 'extra' => $node->extra,
danielebarchiesi@0 1158 ))
danielebarchiesi@0 1159 ->execute();
danielebarchiesi@0 1160 }
danielebarchiesi@0 1161
danielebarchiesi@0 1162 /**
danielebarchiesi@0 1163 * Act on nodes being loaded from the database.
danielebarchiesi@0 1164 *
danielebarchiesi@0 1165 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1166 * (use hook_node_load() to respond to all node loads).
danielebarchiesi@0 1167 *
danielebarchiesi@0 1168 * This hook is invoked during node loading, which is handled by entity_load(),
danielebarchiesi@0 1169 * via classes NodeController and DrupalDefaultEntityController. After the node
danielebarchiesi@0 1170 * information is read from the database or the entity cache, hook_load() is
danielebarchiesi@0 1171 * invoked on the node's content type module, then field_attach_node_revision()
danielebarchiesi@0 1172 * or field_attach_load() is called, then hook_entity_load() is invoked on all
danielebarchiesi@0 1173 * implementing modules, and finally hook_node_load() is invoked on all
danielebarchiesi@0 1174 * implementing modules.
danielebarchiesi@0 1175 *
danielebarchiesi@0 1176 * This hook should only be used to add information that is not in the node or
danielebarchiesi@0 1177 * node revisions table, not to replace information that is in these tables
danielebarchiesi@0 1178 * (which could interfere with the entity cache). For performance reasons,
danielebarchiesi@0 1179 * information for all available nodes should be loaded in a single query where
danielebarchiesi@0 1180 * possible.
danielebarchiesi@0 1181 *
danielebarchiesi@0 1182 * @param $nodes
danielebarchiesi@0 1183 * An array of the nodes being loaded, keyed by nid.
danielebarchiesi@0 1184 *
danielebarchiesi@0 1185 * For a detailed usage example, see node_example.module.
danielebarchiesi@0 1186 *
danielebarchiesi@0 1187 * @ingroup node_api_hooks
danielebarchiesi@0 1188 */
danielebarchiesi@0 1189 function hook_load($nodes) {
danielebarchiesi@0 1190 $result = db_query('SELECT nid, foo FROM {mytable} WHERE nid IN (:nids)', array(':nids' => array_keys($nodes)));
danielebarchiesi@0 1191 foreach ($result as $record) {
danielebarchiesi@0 1192 $nodes[$record->nid]->foo = $record->foo;
danielebarchiesi@0 1193 }
danielebarchiesi@0 1194 }
danielebarchiesi@0 1195
danielebarchiesi@0 1196 /**
danielebarchiesi@0 1197 * Respond to updates to a node.
danielebarchiesi@0 1198 *
danielebarchiesi@0 1199 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1200 * (use hook_node_update() to act on all node updates).
danielebarchiesi@0 1201 *
danielebarchiesi@0 1202 * This hook is invoked from node_save() after the node is updated in the
danielebarchiesi@0 1203 * node table in the database, before field_attach_update() is called, and
danielebarchiesi@0 1204 * before hook_node_update() is invoked.
danielebarchiesi@0 1205 *
danielebarchiesi@0 1206 * @param $node
danielebarchiesi@0 1207 * The node that is being updated.
danielebarchiesi@0 1208 *
danielebarchiesi@0 1209 * @ingroup node_api_hooks
danielebarchiesi@0 1210 */
danielebarchiesi@0 1211 function hook_update($node) {
danielebarchiesi@0 1212 db_update('mytable')
danielebarchiesi@0 1213 ->fields(array('extra' => $node->extra))
danielebarchiesi@0 1214 ->condition('nid', $node->nid)
danielebarchiesi@0 1215 ->execute();
danielebarchiesi@0 1216 }
danielebarchiesi@0 1217
danielebarchiesi@0 1218 /**
danielebarchiesi@0 1219 * Perform node validation before a node is created or updated.
danielebarchiesi@0 1220 *
danielebarchiesi@0 1221 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1222 * (use hook_node_validate() to act on all node validations).
danielebarchiesi@0 1223 *
danielebarchiesi@0 1224 * This hook is invoked from node_validate(), after a user has finished
danielebarchiesi@0 1225 * editing the node and is previewing or submitting it. It is invoked at the end
danielebarchiesi@0 1226 * of all the standard validation steps, and before hook_node_validate() is
danielebarchiesi@0 1227 * invoked.
danielebarchiesi@0 1228 *
danielebarchiesi@0 1229 * To indicate a validation error, use form_set_error().
danielebarchiesi@0 1230 *
danielebarchiesi@0 1231 * Note: Changes made to the $node object within your hook implementation will
danielebarchiesi@0 1232 * have no effect. The preferred method to change a node's content is to use
danielebarchiesi@0 1233 * hook_node_presave() instead.
danielebarchiesi@0 1234 *
danielebarchiesi@0 1235 * @param $node
danielebarchiesi@0 1236 * The node being validated.
danielebarchiesi@0 1237 * @param $form
danielebarchiesi@0 1238 * The form being used to edit the node.
danielebarchiesi@0 1239 * @param $form_state
danielebarchiesi@0 1240 * The form state array.
danielebarchiesi@0 1241 *
danielebarchiesi@0 1242 * @ingroup node_api_hooks
danielebarchiesi@0 1243 */
danielebarchiesi@0 1244 function hook_validate($node, $form, &$form_state) {
danielebarchiesi@0 1245 if (isset($node->end) && isset($node->start)) {
danielebarchiesi@0 1246 if ($node->start > $node->end) {
danielebarchiesi@0 1247 form_set_error('time', t('An event may not end before it starts.'));
danielebarchiesi@0 1248 }
danielebarchiesi@0 1249 }
danielebarchiesi@0 1250 }
danielebarchiesi@0 1251
danielebarchiesi@0 1252 /**
danielebarchiesi@0 1253 * Display a node.
danielebarchiesi@0 1254 *
danielebarchiesi@0 1255 * This hook is invoked only on the module that defines the node's content type
danielebarchiesi@0 1256 * (use hook_node_view() to act on all node views).
danielebarchiesi@0 1257 *
danielebarchiesi@0 1258 * This hook is invoked during node viewing after the node is fully loaded, so
danielebarchiesi@0 1259 * that the node type module can define a custom method for display, or add to
danielebarchiesi@0 1260 * the default display.
danielebarchiesi@0 1261 *
danielebarchiesi@0 1262 * @param $node
danielebarchiesi@0 1263 * The node to be displayed, as returned by node_load().
danielebarchiesi@0 1264 * @param $view_mode
danielebarchiesi@0 1265 * View mode, e.g. 'full', 'teaser', ...
danielebarchiesi@0 1266 * @return
danielebarchiesi@0 1267 * The passed $node parameter should be modified as necessary and returned so
danielebarchiesi@0 1268 * it can be properly presented. Nodes are prepared for display by assembling
danielebarchiesi@0 1269 * a structured array, formatted as in the Form API, in $node->content. As
danielebarchiesi@0 1270 * with Form API arrays, the #weight property can be used to control the
danielebarchiesi@0 1271 * relative positions of added elements. After this hook is invoked,
danielebarchiesi@0 1272 * node_view() calls field_attach_view() to add field views to $node->content,
danielebarchiesi@0 1273 * and then invokes hook_node_view() and hook_node_view_alter(), so if you
danielebarchiesi@0 1274 * want to affect the final view of the node, you might consider implementing
danielebarchiesi@0 1275 * one of these hooks instead.
danielebarchiesi@0 1276 *
danielebarchiesi@0 1277 * @ingroup node_api_hooks
danielebarchiesi@0 1278 */
danielebarchiesi@0 1279 function hook_view($node, $view_mode) {
danielebarchiesi@0 1280 if ($view_mode == 'full' && node_is_page($node)) {
danielebarchiesi@0 1281 $breadcrumb = array();
danielebarchiesi@0 1282 $breadcrumb[] = l(t('Home'), NULL);
danielebarchiesi@0 1283 $breadcrumb[] = l(t('Example'), 'example');
danielebarchiesi@0 1284 $breadcrumb[] = l($node->field1, 'example/' . $node->field1);
danielebarchiesi@0 1285 drupal_set_breadcrumb($breadcrumb);
danielebarchiesi@0 1286 }
danielebarchiesi@0 1287
danielebarchiesi@0 1288 $node->content['myfield'] = array(
danielebarchiesi@0 1289 '#markup' => theme('mymodule_myfield', $node->myfield),
danielebarchiesi@0 1290 '#weight' => 1,
danielebarchiesi@0 1291 );
danielebarchiesi@0 1292
danielebarchiesi@0 1293 return $node;
danielebarchiesi@0 1294 }
danielebarchiesi@0 1295
danielebarchiesi@0 1296 /**
danielebarchiesi@0 1297 * @} End of "addtogroup hooks".
danielebarchiesi@0 1298 */