node.api.php

  1. drupal
    1. 7 modules/node/node.api.php
    2. 8 core/modules/node/node.api.php

Hooks provided by the Node module.

Functions & methods

NameDescription
hook_deleteRespond to node deletion.
hook_formDisplay a node editing form.
hook_insertRespond to creation of a new node.
hook_loadAct on nodes being loaded from the database.
hook_node_accessControls access to a node.
hook_node_access_recordsSet permissions for a node to be written to the database.
hook_node_access_records_alterAlter permissions for a node before it is written to the database.
hook_node_deleteRespond to node deletion.
hook_node_grantsInform the node access system what permissions the user has.
hook_node_grants_alterAlter user access rules when trying to view, edit or delete a node.
hook_node_infoDefine module-provided node types.
hook_node_insertRespond to creation of a new node.
hook_node_loadAct on nodes being loaded from the database.
hook_node_operationsAdd mass node operations.
hook_node_predeleteAct before node deletion.
hook_node_prepareAct on a node object about to be shown on the add/edit form.
hook_node_presaveAct on a node being inserted or updated.
hook_node_revision_deleteRespond to deletion of a node revision.
hook_node_search_resultAct on a node being displayed as a search result.
hook_node_submitAct on a node after validated form values have been copied to it.
hook_node_type_deleteRespond to node type deletion.
hook_node_type_insertRespond to node type creation.
hook_node_type_updateRespond to node type updates.
hook_node_updateRespond to updates to a node.
hook_node_update_indexAct on a node being indexed for searching.
hook_node_validatePerform node validation before a node is created or updated.
hook_node_viewAct on a node that is being assembled before rendering.
hook_node_view_alterAlter the results of node_view().
hook_prepareAct on a node object about to be shown on the add/edit form.
hook_rankingProvide additional methods of scoring for core search results for nodes.
hook_updateRespond to updates to a node.
hook_validatePerform node validation before a node is created or updated.
hook_viewDisplay a node.

File

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