panels.install 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. <?php
  2. /**
  3. * @file
  4. */
  5. /**
  6. * Test requirements for installation and running.
  7. */
  8. function panels_requirements($phase) {
  9. $function = "panels_requirements_$phase";
  10. return function_exists($function) ? $function() : array();
  11. }
  12. /**
  13. * Check install-time requirements.
  14. */
  15. function panels_requirements_install() {
  16. $requirements = array();
  17. $t = get_t();
  18. // Assume that if the user is running an installation profile that both
  19. // Panels and CTools are the same release.
  20. if (!(defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'install')) {
  21. // Apparently the install process doesn't include .module files,
  22. // so we need to force the issue in order for our versioning
  23. // check to work.
  24. if (!defined('PANELS_REQUIRED_CTOOLS_API')) {
  25. include_once drupal_get_path('module', 'panels') . '/panels.module';
  26. }
  27. // In theory we should check module_exists, but Drupal's gating should
  28. // actually prevent us from getting here otherwise.
  29. if (!defined('CTOOLS_API_VERSION')) {
  30. include_once drupal_get_path('module', 'ctools') . '/ctools.module';
  31. }
  32. if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) {
  33. $requirements['panels_ctools'] = array(
  34. 'title' => $t('CTools API Version'),
  35. 'value' => CTOOLS_API_VERSION,
  36. 'severity' => REQUIREMENT_ERROR,
  37. 'description' => t('The CTools API version is too old for Panels. Panels needs at least %version.', array('%version' => PANELS_REQUIRED_CTOOLS_API)),
  38. );
  39. }
  40. }
  41. return $requirements;
  42. }
  43. /**
  44. * Implements of hook_schema().
  45. */
  46. function panels_schema() {
  47. // This should always point to our 'current' schema. This makes it relatively
  48. // easy to keep a record of schema as we make changes to it.
  49. return panels_schema_10();
  50. }
  51. function panels_schema_10() {
  52. $schema = panels_schema_9();
  53. // Add primary key to panels_allowed_types table.
  54. $schema['panels_allowed_types']['primary key'] = array('module', 'type');
  55. return $schema;
  56. }
  57. function panels_schema_9() {
  58. $schema = panels_schema_8();
  59. $schema['panels_allowed_types'] = array(
  60. 'fields' => array(
  61. 'module' => array(
  62. 'description' => 'The name of the module requiring allowed type settings.',
  63. 'type' => 'varchar',
  64. 'length' => 255,
  65. 'not null' => TRUE,
  66. 'default' => '',
  67. ),
  68. 'type' => array(
  69. 'description' => 'Ctools content type to allow.',
  70. 'type' => 'varchar',
  71. 'length' => 255,
  72. 'not null' => TRUE,
  73. 'default' => '',
  74. ),
  75. 'allowed' => array(
  76. 'description' => 'A boolean for if the type is allowed or not.',
  77. 'type' => 'int',
  78. 'size' => 'tiny',
  79. 'default' => 1,
  80. ),
  81. ),
  82. 'indexes' => array(
  83. 'type_idx' => array('type'),
  84. ),
  85. );
  86. return $schema;
  87. }
  88. function panels_schema_8() {
  89. $schema = panels_schema_7();
  90. // Add the storage type and id columns.
  91. $schema['panels_display']['fields']['storage_type'] = array(
  92. 'type' => 'varchar',
  93. 'length' => 255,
  94. 'default' => '',
  95. );
  96. $schema['panels_display']['fields']['storage_id'] = array(
  97. 'type' => 'varchar',
  98. 'length' => 255,
  99. 'default' => '',
  100. );
  101. return $schema;
  102. }
  103. function panels_schema_7() {
  104. $schema = panels_schema_6();
  105. // Update field lengths to 255 chars.
  106. $schema['panels_pane']['fields']['subtype']['length'] = '255';
  107. $schema['panels_pane']['fields']['panel']['length'] = '255';
  108. $schema['panels_pane']['fields']['type']['length'] = '255';
  109. return $schema;
  110. }
  111. function panels_schema_6() {
  112. $schema = panels_schema_5();
  113. $schema['cache_panels'] = drupal_get_schema_unprocessed('system', 'cache');
  114. return $schema;
  115. }
  116. function panels_schema_5() {
  117. $schema = panels_schema_4();
  118. $schema['panels_display']['fields']['uuid'] = array(
  119. 'type' => 'char',
  120. 'length' => '36',
  121. );
  122. $schema['panels_display']['export']['key'] = 'uuid';
  123. $schema['panels_display']['export']['key name'] = 'UUID';
  124. $schema['panels_pane']['fields']['uuid'] = array(
  125. 'type' => 'char',
  126. 'length' => '36',
  127. );
  128. $schema['panels_pane']['export']['key'] = 'uuid';
  129. $schema['panels_pane']['export']['key name'] = 'UUID';
  130. return $schema;
  131. }
  132. function panels_schema_4() {
  133. $schema = panels_schema_3();
  134. $schema['panels_pane']['fields']['locks'] = array(
  135. 'type' => 'text',
  136. 'size' => 'big',
  137. 'serialize' => TRUE,
  138. 'object default' => array(),
  139. 'initial' => array(),
  140. );
  141. return $schema;
  142. }
  143. /**
  144. * Schema from the D6 version.
  145. */
  146. function panels_schema_3() {
  147. // Schema 3 is now locked. If you need to make changes, please create
  148. // schema 4 and add them.
  149. $schema = array();
  150. $schema['panels_display'] = array(
  151. 'export' => array(
  152. 'object' => 'panels_display',
  153. 'bulk export' => FALSE,
  154. 'export callback' => 'panels_export_display',
  155. 'can disable' => FALSE,
  156. 'identifier' => 'display',
  157. ),
  158. 'fields' => array(
  159. 'did' => array(
  160. 'type' => 'serial',
  161. 'not null' => TRUE,
  162. 'no export' => TRUE,
  163. ),
  164. 'layout' => array(
  165. 'type' => 'varchar',
  166. 'length' => '255',
  167. 'default' => '',
  168. ),
  169. 'layout_settings' => array(
  170. 'type' => 'text',
  171. 'size' => 'big',
  172. 'serialize' => TRUE,
  173. 'object default' => array(),
  174. 'initial' => array(),
  175. ),
  176. 'panel_settings' => array(
  177. 'type' => 'text',
  178. 'size' => 'big',
  179. 'serialize' => TRUE,
  180. 'object default' => array(),
  181. 'initial' => array(),
  182. ),
  183. 'cache' => array(
  184. 'type' => 'text',
  185. 'serialize' => TRUE,
  186. 'object default' => array(),
  187. 'initial' => array(),
  188. ),
  189. 'title' => array(
  190. 'type' => 'varchar',
  191. 'length' => '255',
  192. 'default' => '',
  193. ),
  194. 'hide_title' => array(
  195. 'type' => 'int',
  196. 'size' => 'tiny',
  197. 'default' => 0,
  198. 'no export' => TRUE,
  199. ),
  200. 'title_pane' => array(
  201. 'type' => 'int',
  202. 'default' => 0,
  203. 'no export' => TRUE,
  204. ),
  205. ),
  206. 'primary key' => array('did'),
  207. );
  208. $schema['panels_pane'] = array(
  209. 'export' => array(
  210. 'can disable' => FALSE,
  211. 'identifier' => 'pane',
  212. 'bulk export' => FALSE,
  213. ),
  214. 'fields' => array(
  215. 'pid' => array(
  216. 'type' => 'serial',
  217. 'not null' => TRUE,
  218. ),
  219. 'did' => array(
  220. 'type' => 'int',
  221. 'not null' => TRUE,
  222. 'default' => 0,
  223. 'no export' => TRUE,
  224. ),
  225. 'panel' => array(
  226. 'type' => 'varchar',
  227. 'length' => '32',
  228. 'default' => '',
  229. ),
  230. 'type' => array(
  231. 'type' => 'varchar',
  232. 'length' => '32',
  233. 'default' => '',
  234. ),
  235. 'subtype' => array(
  236. 'type' => 'varchar',
  237. 'length' => '64',
  238. 'default' => '',
  239. ),
  240. 'shown' => array(
  241. 'type' => 'int',
  242. 'size' => 'tiny',
  243. 'default' => 1,
  244. ),
  245. 'access' => array(
  246. 'type' => 'text',
  247. 'size' => 'big',
  248. 'serialize' => TRUE,
  249. 'object default' => array(),
  250. 'initial' => array(),
  251. ),
  252. 'configuration' => array(
  253. 'type' => 'text',
  254. 'size' => 'big',
  255. 'serialize' => TRUE,
  256. 'object default' => array(),
  257. 'initial' => array(),
  258. ),
  259. 'cache' => array(
  260. 'type' => 'text',
  261. 'size' => 'big',
  262. 'serialize' => TRUE,
  263. 'object default' => array(),
  264. 'initial' => array(),
  265. ),
  266. 'style' => array(
  267. 'type' => 'text',
  268. 'size' => 'big',
  269. 'serialize' => TRUE,
  270. 'object default' => array(),
  271. 'initial' => array(),
  272. ),
  273. 'css' => array(
  274. 'type' => 'text',
  275. 'size' => 'big',
  276. 'serialize' => TRUE,
  277. 'object default' => array(),
  278. 'initial' => array(),
  279. ),
  280. 'extras' => array(
  281. 'type' => 'text',
  282. 'size' => 'big',
  283. 'serialize' => TRUE,
  284. 'object default' => array(),
  285. 'initial' => array(),
  286. ),
  287. 'position' => array(
  288. 'type' => 'int',
  289. 'size' => 'small',
  290. 'default' => 0,
  291. ),
  292. ),
  293. 'primary key' => array('pid'),
  294. 'indexes' => array(
  295. 'did_idx' => array('did'),
  296. ),
  297. );
  298. $schema['panels_renderer_pipeline'] = array(
  299. 'description' => 'Contains renderer pipelines for Panels. Each pipeline contains one or more renderers and access rules to select which renderer gets used.',
  300. 'export' => array(
  301. 'identifier' => 'pipeline',
  302. 'bulk export' => TRUE,
  303. 'primary key' => 'rpid',
  304. 'api' => array(
  305. 'owner' => 'panels',
  306. 'api' => 'pipelines',
  307. 'minimum_version' => 1,
  308. 'current_version' => 1,
  309. ),
  310. ),
  311. 'fields' => array(
  312. 'rpid' => array(
  313. 'type' => 'serial',
  314. 'description' => 'A database primary key to ensure uniqueness.',
  315. 'not null' => TRUE,
  316. 'no export' => TRUE,
  317. ),
  318. 'name' => array(
  319. 'type' => 'varchar',
  320. 'length' => '255',
  321. 'description' => 'Unique ID for this content. Used to identify it programmatically.',
  322. ),
  323. 'admin_title' => array(
  324. 'type' => 'varchar',
  325. 'length' => '255',
  326. 'description' => 'Administrative title for this pipeline.',
  327. ),
  328. 'admin_description' => array(
  329. 'type' => 'text',
  330. 'size' => 'big',
  331. 'description' => 'Administrative description for this pipeline.',
  332. 'object default' => '',
  333. ),
  334. 'weight' => array(
  335. 'type' => 'int',
  336. 'size' => 'small',
  337. 'default' => 0,
  338. ),
  339. 'settings' => array(
  340. 'type' => 'text',
  341. 'size' => 'big',
  342. 'description' => 'Serialized settings for the actual pipeline. The contents of this field are up to the plugin that uses it.',
  343. 'serialize' => TRUE,
  344. 'object default' => array(),
  345. ),
  346. ),
  347. 'primary key' => array('rpid'),
  348. );
  349. $schema['panels_layout'] = array(
  350. 'description' => 'Contains exportable customized layouts for this site.',
  351. 'export' => array(
  352. 'identifier' => 'layout',
  353. 'bulk export' => TRUE,
  354. 'primary key' => 'lid',
  355. 'api' => array(
  356. 'owner' => 'panels',
  357. 'api' => 'layouts',
  358. 'minimum_version' => 1,
  359. 'current_version' => 1,
  360. ),
  361. ),
  362. 'fields' => array(
  363. 'lid' => array(
  364. 'type' => 'serial',
  365. 'description' => 'A database primary key to ensure uniqueness.',
  366. 'not null' => TRUE,
  367. 'no export' => TRUE,
  368. ),
  369. 'name' => array(
  370. 'type' => 'varchar',
  371. 'length' => '255',
  372. 'description' => 'Unique ID for this content. Used to identify it programmatically.',
  373. ),
  374. 'admin_title' => array(
  375. 'type' => 'varchar',
  376. 'length' => '255',
  377. 'description' => 'Administrative title for this layout.',
  378. ),
  379. 'admin_description' => array(
  380. 'type' => 'text',
  381. 'size' => 'big',
  382. 'description' => 'Administrative description for this layout.',
  383. 'object default' => '',
  384. ),
  385. 'category' => array(
  386. 'type' => 'varchar',
  387. 'length' => '255',
  388. 'description' => 'Administrative category for this layout.',
  389. ),
  390. 'plugin' => array(
  391. 'type' => 'varchar',
  392. 'length' => '255',
  393. 'description' => 'The layout plugin that owns this layout.',
  394. ),
  395. 'settings' => array(
  396. 'type' => 'text',
  397. 'size' => 'big',
  398. 'description' => 'Serialized settings for the actual layout. The contents of this field are up to the plugin that uses it.',
  399. 'serialize' => TRUE,
  400. 'object default' => array(),
  401. ),
  402. ),
  403. 'primary key' => array('lid'),
  404. );
  405. return $schema;
  406. }
  407. /**
  408. * Change panels_display.layout to match the size of panels_layout.name.
  409. */
  410. function panels_update_7300() {
  411. // Load the schema.
  412. $schema = panels_schema_3();
  413. $table = 'panels_display';
  414. $field = 'layout';
  415. $spec = $schema[$table]['fields'][$field];
  416. // Re-define the column.
  417. db_change_field($table, $field, $field, $spec);
  418. return t('Changed the panels_display.layout field to the correct size.');
  419. }
  420. /**
  421. * Add lock field to panels_pane table.
  422. */
  423. function panels_update_7301() {
  424. // Load the schema.
  425. // Due to a previous failure, the field may already exist:
  426. $schema = panels_schema_4();
  427. $table = 'panels_pane';
  428. $field = 'locks';
  429. if (!db_field_exists($table, $field)) {
  430. $spec = $schema[$table]['fields'][$field];
  431. // Core does not properly respect 'initial' and 'serialize'.
  432. unset($spec['initial']);
  433. // Re-define the column.
  434. db_add_field($table, $field, $spec);
  435. return t('Added panels_pane.lock field.');
  436. }
  437. return t('panels_pane.lock field already existed, update skipped.');
  438. }
  439. /**
  440. * Adding universally unique identifiers to panels.
  441. *
  442. * Note: This update hook is not written well. It calls apis which uses the
  443. * most updated drupal database, causing missing columns or tables errors. To
  444. * mitigate the issue, we've added updates from 7303 and 7305. Future updates
  445. * should go below the 7305 update.
  446. *
  447. * See https://www.drupal.org/node/2787123 for more info.
  448. */
  449. function panels_update_7302() {
  450. if (!module_load_include('inc', 'ctools', 'includes/uuid')) {
  451. throw new DrupalUpdateException(t('Ctools UUID support not detected. You must update to a more recent version of the ctools module.'));
  452. }
  453. // Run the 7303 update first to avoid caching issues.
  454. // This *probably* should be placed right above update 7305, however it was
  455. // tested here and re-testing this update is difficult, so it stays here.
  456. panels_update_7303();
  457. // Load the schema.
  458. $schema = panels_schema_5();
  459. $msg = array();
  460. // Add the uuid column to the pane table.
  461. $table = 'panels_pane';
  462. $field = 'uuid';
  463. // Due to a previous failure, the column may already exist:
  464. if (!db_field_exists($table, $field)) {
  465. $spec = $schema[$table]['fields'][$field];
  466. db_add_field($table, $field, $spec);
  467. $msg[] = t('Added panels_pane.uuid column.');
  468. }
  469. // Add the uuid column to the display table.
  470. $table = 'panels_display';
  471. $field = 'uuid';
  472. // Due to a previous failure, the column may already exist:
  473. if (!db_field_exists($table, $field)) {
  474. $spec = $schema[$table]['fields'][$field];
  475. db_add_field($table, $field, $spec);
  476. $msg[] = t('Added panels_display.uuid column.');
  477. }
  478. if (empty($msg)) {
  479. $msg[] = t('UUID column already present in the panels_display & panels_pane tables.');
  480. }
  481. // Update all DB-based panes & displays to ensure that they all contain a UUID.
  482. $display_dids = db_select('panels_display')
  483. ->fields('panels_display', array('did'))
  484. ->condition(db_or()
  485. ->condition('uuid', '')
  486. ->isNull('uuid')
  487. )
  488. ->execute()
  489. ->fetchCol();
  490. // Check the panes as well, for paranoia.
  491. $pane_dids = db_select('panels_pane')
  492. ->distinct()
  493. ->fields('panels_pane', array('did'))
  494. ->condition(db_or()
  495. ->condition('uuid', '')
  496. ->isNull('uuid')
  497. )
  498. ->execute()
  499. ->fetchCol();
  500. $dids = array_unique(array_merge($display_dids, $pane_dids));
  501. // Before using panels_save_display(), we have to make sure any new fields
  502. // are added from future updates.
  503. panels_update_7305();
  504. // If the Panels module is disabled we don't have access to
  505. // panels_load_displays().
  506. if (!function_exists('panels_load_displays')) {
  507. module_load_include('module', 'panels');
  508. }
  509. if ($displays = panels_load_displays($dids)) {
  510. foreach ($displays as $display) {
  511. // A display save also triggers pane saves.
  512. panels_save_display($display);
  513. }
  514. $msg[] = t('Generated UUIDs for database-based panel displays and panes.');
  515. }
  516. else {
  517. $msg[] = t('No database-based panel displays or panes for which to generate UUIDs.');
  518. }
  519. return implode("\n", $msg);
  520. }
  521. /**
  522. * Add a custom cache table for Panels.
  523. */
  524. function panels_update_7303() {
  525. $schema = panels_schema_6();
  526. $table_name = 'cache_panels';
  527. if (!db_table_exists($table_name)) {
  528. db_create_table($table_name, $schema[$table_name]);
  529. }
  530. }
  531. /**
  532. * Update "panels_pane" table field lengths to 255 chars.
  533. */
  534. function panels_update_7304() {
  535. $schema = panels_schema_7();
  536. $update_fields = array(
  537. 'panels_pane' => array('subtype', 'panel', 'type'),
  538. );
  539. foreach ($update_fields as $table => $fields) {
  540. foreach ($fields as $field_name) {
  541. db_change_field($table, $field_name, $field_name, $schema[$table]['fields'][$field_name]);
  542. }
  543. }
  544. }
  545. /**
  546. * Add the "storage_type" and "storage_id" columns to "panels_display".
  547. */
  548. function panels_update_7305() {
  549. $schema = panels_schema_8();
  550. $new_fields = array(
  551. 'panels_display' => array('storage_type', 'storage_id'),
  552. );
  553. foreach ($new_fields as $table => $fields) {
  554. foreach ($fields as $field_name) {
  555. // Due to a previous failure, the column may already exist:
  556. if (!db_field_exists($table, $field_name)) {
  557. db_add_field($table, $field_name, $schema[$table]['fields'][$field_name]);
  558. }
  559. }
  560. }
  561. }
  562. /**
  563. * Set the storage type and id on existing page manager panels displays.
  564. */
  565. function panels_update_7306() {
  566. if (!db_table_exists('page_manager_handlers')) {
  567. return t('Skipping update - page_manager is not installed.');
  568. }
  569. // Get all page_manager_handlers that have a panels context.
  570. $result = db_query("SELECT pm.name, pm.conf FROM {page_manager_handlers} pm WHERE pm.handler = 'panel_context'");
  571. $page_manager_panels = array();
  572. foreach ($result as $row) {
  573. $conf = unserialize($row->conf);
  574. if (isset($conf['did'])) {
  575. $page_manager_panels[$conf['did']] = $row->name;
  576. }
  577. }
  578. if (!empty($page_manager_panels)) {
  579. // Check panels displays that only have empty storage types.
  580. $result = db_query("SELECT pd.did FROM {panels_display} pd WHERE pd.did IN (:dids) AND storage_type = ''", array(':dids' => array_keys($page_manager_panels)));
  581. foreach ($result as $row) {
  582. db_update('panels_display')
  583. ->fields(array(
  584. 'storage_type' => 'page_manager',
  585. 'storage_id' => $page_manager_panels[$row->did],
  586. ))
  587. ->condition('did', $row->did)
  588. ->execute();
  589. }
  590. }
  591. }
  592. /**
  593. * Add a custom table for allowed types.
  594. */
  595. function panels_update_7307() {
  596. $schema = panels_schema_9();
  597. $table_name = 'panels_allowed_types';
  598. if (!db_table_exists($table_name)) {
  599. db_create_table($table_name, $schema[$table_name]);
  600. }
  601. /*
  602. The version of this update hook in release 3.8 included code that
  603. converted storage of allowed_types configuration from variables to the new
  604. table, and also deleted existing allowed_types configuration variables.
  605. See https://www.drupal.org/node/2479879.
  606. In order to prevent data loss on sites that had not yet updated to 3.8, the
  607. conversion and variable-deletion code has been removed from this update hook.
  608. */
  609. }
  610. /**
  611. * Rename style permissions.
  612. */
  613. function panels_update_7308() {
  614. $permissions = array(
  615. 'administer panels display styles',
  616. 'administer panels pane styles',
  617. 'administer panels region styles',
  618. );
  619. foreach (array_keys(user_roles(TRUE, 'administer panels styles')) as $rid) {
  620. user_role_grant_permissions($rid, $permissions);
  621. }
  622. }
  623. /**
  624. * Add primary key to panels_allowed_types table.
  625. */
  626. function panels_update_7309() {
  627. db_add_primary_key('panels_allowed_types', array('module', 'type'));
  628. }