hosting_package.module

Defines package node types

Packages are somewhat analogous to Drupal.org projects. i.e.: components that can be installed onto Drupal sites.

Functions

Namesort descending Description
hosting_get_default_profile @todo document this function
hosting_get_package @todo document this function
hosting_get_packages_by_type @todo document this function
hosting_get_profiles Return a list of available install profiles.
hosting_get_profile_languages @todo document this function
hosting_get_profile_platforms @todo document this function
hosting_nodeapi_package_delete_revision @todo document this function
hosting_package_block_visibility Control block visibility.
hosting_package_delete Implements hook_delete().
hosting_package_hosting_site_site_list_filters Implements hook_hosting_site_site_list_filters().
hosting_package_insert Implements hook_insert().
hosting_package_load Implements hook_load().
hosting_package_node_access Implements hook_node_access(). @todo: check that we don't want to manage this through node_grants.
hosting_package_node_info Implements hook_node_info().
hosting_package_node_load @todo document this function
hosting_package_permission Implements hook_permission().
hosting_package_sync Sync the package and package release nodes with the information retrieved from the verify task
hosting_package_update Implements hook_update().
hosting_package_view Implements hook_view().
hosting_package_views_api Implements hook_views_api().
_hosting_language_name Lookup a language name based on the iso language code.
_hosting_language_names Return names of the languages available
_hosting_package_load A generic method for finding whichever packages you are looking for.
_hosting_package_plural_map @todo document this function
_hosting_package_types

Constants

File

package/hosting_package.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Defines package node types
  5. *
  6. * Packages are somewhat analogous to Drupal.org projects. i.e.: components that
  7. * can be installed onto Drupal sites.
  8. */
  9. define('HOSTING_PACKAGE_INSTANCE_EXCLUDE', -1);
  10. require_once 'hosting_package.instance.inc';
  11. function _hosting_package_types() {
  12. return array(
  13. 'profile' => t('Installation Profiles'),
  14. 'module' => t('Modules'),
  15. 'theme' => t('Themes'),
  16. );
  17. }
  18. /**
  19. * Implements hook_node_info().
  20. */
  21. function hosting_package_node_info() {
  22. #package management
  23. $types["package"] = array(
  24. "type" => 'package',
  25. "name" => t('Package'),
  26. 'base' => 'hosting_package',
  27. "has_title" => FALSE,
  28. "title_label" => '',
  29. "description" => hosting_node_help("package"),
  30. "has_body" => 0,
  31. "body_label" => '',
  32. "min_word_count" => 0,
  33. );
  34. return $types;
  35. }
  36. /**
  37. * @todo document this function
  38. */
  39. function hosting_package_node_load($arg) {
  40. if (!is_numeric($arg)) {
  41. return FALSE;
  42. }
  43. if ($node = node_load($arg)) {
  44. if (in_array($node->type, array('site', 'platform'))) {
  45. return $node;
  46. }
  47. }
  48. return FALSE;
  49. }
  50. /**
  51. * Implements hook_permission().
  52. */
  53. function hosting_package_permission() {
  54. return array(
  55. 'create package' => array(
  56. 'title' => t('create package'),
  57. ),
  58. 'view package' => array(
  59. 'title' => t('view package'),
  60. ),
  61. 'edit package' => array(
  62. 'title' => t('edit package'),
  63. ),
  64. 'delete package' => array(
  65. 'title' => t('delete package'),
  66. ),
  67. );
  68. }
  69. /**
  70. * Implements hook_node_access().
  71. * @todo: check that we don't want to manage this through node_grants.
  72. */
  73. function hosting_package_node_access($node, $op, $account) {
  74. switch ($op) {
  75. case 'create':
  76. return user_access('create package', $account);
  77. break;
  78. case 'view':
  79. return user_access('view package', $account);
  80. break;
  81. case 'update':
  82. return user_access('edit package', $account);
  83. break;
  84. case 'delete':
  85. return user_access('delete package', $account);
  86. break;
  87. default:
  88. break;
  89. }
  90. }
  91. /**
  92. * Return a list of available install profiles.
  93. *
  94. * @param null $platform_nid
  95. * Only load install profiles available on this platform.
  96. *
  97. * @param string $field
  98. * The field to use for the value of the return array.
  99. *
  100. * @return array
  101. * The list of available install profiles, ready to use as #options in a form.
  102. */
  103. function hosting_get_profiles($platform_nid = NULL, $field = 'title') {
  104. $profiles = array();
  105. if (!is_null($platform_nid)) {
  106. $instances = hosting_package_instances_load(array(
  107. 'i.rid' => $platform_nid,
  108. 'p.package_type' => 'profile',
  109. 'n.status' => 1,
  110. ));
  111. }
  112. else {
  113. $instances = hosting_package_instances_load(array(
  114. 'p.package_type' => 'profile',
  115. 'n.status' => 1,
  116. 'r.type' => 'platform',
  117. ));
  118. }
  119. // Prepare list of available profiles, preventing the use of blocked ones.
  120. foreach ($instances as $iid => $instance) {
  121. if (!in_array($instance->short_name, variable_get('hosting_blocked_profiles', array('hostslave', 'hostmaster')))) {
  122. $profiles[$instance->package_id] = $instance->$field;
  123. }
  124. }
  125. return $profiles;
  126. }
  127. /**
  128. * @todo document this function
  129. */
  130. function hosting_get_profile_platforms($profile, $check_old_short_name = FALSE) {
  131. $defaults = array('default', 'standard', 'minimal', 'testing');
  132. $platforms = array();
  133. $instances = hosting_package_instances_load(array(
  134. 'i.package_id' => $profile,
  135. 'n.status' => 1,
  136. 'r.status' => 1,
  137. 'r.type' => 'platform',
  138. ));
  139. if ($check_old_short_name) {
  140. $instances = array_merge($instances, hosting_package_instances_load(array(
  141. 'p.old_short_name' => $instances[key($instances)]->short_name,
  142. 'n.status' => 1,
  143. 'r.status' => 1,
  144. 'r.type' => 'platform',
  145. )));
  146. }
  147. foreach ($instances as $iid => $instance) {
  148. $platform = node_load($instance->rid);
  149. // this is one of the default profiles
  150. if (in_array($instance->short_name, $defaults) &&
  151. sizeof(array_diff(array_values($platform->profiles), $defaults)) &&
  152. variable_get('hosting_ignore_default_profiles', FALSE)) {
  153. // there are other profiles available on this platform. skip this.
  154. continue;
  155. }
  156. if ($platform->platform_status != HOSTING_PLATFORM_DELETED) {
  157. $platforms[$instance->rid] = $platform->title;
  158. }
  159. }
  160. return $platforms;
  161. }
  162. /**
  163. * @todo document this function
  164. */
  165. function hosting_get_profile_languages($profile = NULL, $platform = NULL) {
  166. $languages['en'] = _hosting_language_name('en');
  167. if ($profile && $platform) {
  168. $instance = hosting_package_instance_load(array(
  169. 'i.rid' => $platform,
  170. 'i.package_id' => $profile,
  171. ));
  172. $languages = array_merge($languages, $instance->languages);
  173. }
  174. else {
  175. $result = db_query("SELECT DISTINCT language FROM {hosting_package_languages}");
  176. while ($lang = $result->fetch()) {
  177. $languages[$lang->language] = _hosting_language_name($lang->language);
  178. }
  179. }
  180. return $languages;
  181. }
  182. /**
  183. * A generic method for finding whichever packages you are looking for.
  184. *
  185. * This works similarly to node_load's implementation, but it will only look
  186. * for fields related to packages.
  187. *
  188. * @param
  189. * An associated array containing the following properties
  190. * - name => A string containing the friendly name of the package
  191. * - short_name => The name of the drupal package in the system table
  192. * - old_short_name => The name that a package used to be called, for
  193. * migration purposes.
  194. * - package_type => The type of package. (theme|module|profile|engine)
  195. *
  196. * @return array|bool
  197. */
  198. function _hosting_package_load($param) {
  199. // Turn the conditions into a query.
  200. foreach ($param as $key => $value) {
  201. $cond[] = 'p.' . db_escape_table($key) . " = '%s'";
  202. $arguments[] = $value;
  203. }
  204. $cond = implode(' AND ', $cond);
  205. // TODO convert this statement to a DBTNG dynamic query.
  206. $result = db_query('SELECT n.nid FROM {node} n left join {hosting_package} p on n.nid = p.nid WHERE ' . $cond, $arguments);
  207. while ($nid = $result->fetch()) {
  208. $return[$nid->nid] = node_load($nid->nid);
  209. }
  210. if (sizeof($return)) {
  211. return $return;
  212. }
  213. return NULL;
  214. }
  215. /**
  216. * @todo document this function
  217. */
  218. function hosting_get_packages_by_type($type) {
  219. $result = db_query("SELECT nid FROM {hosting_package} WHERE package_type = :package_type", array(':package_type' => $type));
  220. if ($nid = $result->fetchField()) {
  221. return node_load($nid);
  222. }
  223. return FALSE;
  224. }
  225. /**
  226. * @todo document this function
  227. */
  228. function hosting_get_default_profile($default = NULL) {
  229. if ($p = hosting_get_package(variable_get('hosting_default_profile', 'standard'), 'profile')) {
  230. return $p->nid;
  231. }
  232. elseif ($p = hosting_get_package('standard', 'profile')) {
  233. return $p->nid;
  234. }
  235. elseif ($p = hosting_get_package('default', 'profile')) {
  236. return $p->nid;
  237. }
  238. return $default;
  239. }
  240. /**
  241. * @todo document this function
  242. */
  243. function hosting_get_package($short_name, $type) {
  244. $result = db_query("SELECT nid
  245. FROM {hosting_package}
  246. WHERE short_name = :short_name
  247. AND package_type = :type
  248. ", array(
  249. ':short_name' => $short_name,
  250. ':type' => $type,
  251. )
  252. );
  253. if ($nid = $result->fetchField()) {
  254. return node_load($nid);
  255. }
  256. return FALSE;
  257. }
  258. /**
  259. * Implements hook_insert().
  260. */
  261. function hosting_package_insert($node) {
  262. $id = db_insert('hosting_package')
  263. ->fields(array(
  264. 'vid' => $node->vid,
  265. 'nid' => $node->nid,
  266. 'package_type' => $node->package_type,
  267. 'short_name' => $node->short_name,
  268. 'old_short_name' => $node->old_short_name,
  269. 'description ' => $node->description,
  270. ))
  271. ->execute();
  272. }
  273. /**
  274. * Implements hook_update().
  275. *
  276. * As an existing node is being updated in the database, we need to do our own
  277. * database updates.
  278. */
  279. function hosting_package_update($node) {
  280. // if this is a new node or we're adding a new revision,
  281. if (!empty($node->revision)) {
  282. hosting_package_insert($node);
  283. }
  284. else {
  285. db_update('hosting_package')
  286. ->fields(array(
  287. 'package_type' => $node->package_type,
  288. 'short_name' => $node->short_name,
  289. 'old_short_name' => $node->old_short_name,
  290. 'description' => $node->description,
  291. ))
  292. ->condition('nid', $node->nid)
  293. ->execute();
  294. }
  295. }
  296. /**
  297. * @todo document this function
  298. */
  299. function hosting_nodeapi_package_delete_revision(&$node) {
  300. db_delete('hosting_package')
  301. ->condition('vid', $node->vid)
  302. ->execute();
  303. }
  304. /**
  305. * Implements hook_delete().
  306. */
  307. function hosting_package_delete($node) {
  308. db_delete('hosting_package')
  309. ->condition('nid', $node->nid)
  310. ->execute();
  311. }
  312. /**
  313. * Implements hook_load().
  314. */
  315. function hosting_package_load($nodes) {
  316. foreach ($nodes as $nid => &$node) {
  317. $additions = db_query('SELECT package_type, short_name, old_short_name, description FROM {hosting_package} WHERE vid = :vid', array(':vid' => $node->vid))->fetch();
  318. foreach ($additions as $property => &$value) {
  319. $node->$property = $value;
  320. }
  321. }
  322. }
  323. /**
  324. * Implements hook_view().
  325. */
  326. function hosting_package_view($node, $teaser = FALSE, $page = FALSE) {
  327. hosting_set_breadcrumb($node);
  328. $node->content['info']['#prefix'] = '<div id="hosting-package-info">';
  329. $node->content['info']['package_type'] = array(
  330. '#type' => 'item',
  331. '#title' => t('Package Type'),
  332. '#markup' => filter_xss($node->package_type),
  333. );
  334. $node->content['info']['short_name'] = array(
  335. '#type' => 'item',
  336. '#title' => t('Project Name'),
  337. '#markup' => filter_xss($node->short_name),
  338. );
  339. if (!empty($node->old_short_name)) {
  340. $node->content['info']['old_short_name'] = array(
  341. '#type' => 'item',
  342. '#title' => t('Previous Project Name'),
  343. '#markup' => filter_xss($node->old_short_name),
  344. );
  345. }
  346. $node->content['info']['#suffix'] = '</div>';
  347. return $node;
  348. }
  349. /**
  350. * Implements hook_hosting_site_site_list_filters().
  351. */
  352. function hosting_package_hosting_site_site_list_filters() {
  353. return array('profile');
  354. }
  355. /**
  356. * Return names of the languages available
  357. */
  358. function _hosting_language_names($languages) {
  359. foreach ($languages as $language) {
  360. // Try to use verbose language name
  361. $return[$language] = _hosting_language_name($language);
  362. }
  363. return $return;
  364. }
  365. /**
  366. * Lookup a language name based on the iso language code.
  367. */
  368. function _hosting_language_name($language) {
  369. $name = $language;
  370. include_once DRUPAL_ROOT . '/includes/iso.inc';
  371. $locales = _locale_get_predefined_list();
  372. if (isset($locales[$language])) {
  373. $name = $locales[$language][0];
  374. if (isset($locales[$language][1])) {
  375. $name .= ' ' . t('(@language)', array('@language' => $locales[$language][1]));
  376. }
  377. }
  378. return $name;
  379. }
  380. /**
  381. * @todo document this function
  382. */
  383. function _hosting_package_plural_map($key = NULL) {
  384. static $plural_map = array(
  385. 'modules' => 'module',
  386. 'themes' => 'theme',
  387. 'profiles' => 'profile',
  388. 'engines' => 'engine',
  389. 'platforms' => 'platform',
  390. );
  391. if (is_null($key)) {
  392. return $plural_map;
  393. }
  394. return (array_key_exists($key, $plural_map)) ? $plural_map[$key] : $key;
  395. }
  396. /**
  397. * Sync the package and package release nodes with the information
  398. * retrieved from the verify task
  399. *
  400. * @todo Make this prettier.
  401. */
  402. function hosting_package_sync(&$data) {
  403. foreach ($data as $plural => $packages) {
  404. $type = _hosting_package_plural_map($plural);
  405. foreach ($packages as $short_name => $file) {
  406. $name = isset($file['info']['name']) ? $file['info']['name'] : $short_name;
  407. if (!($package = hosting_get_package($short_name, $type))) {
  408. // Create a new package.
  409. $package = new stdClass();
  410. $package->type = 'package';
  411. $package->uid = 1;
  412. $package->package_type = $type;
  413. $package->short_name = $short_name;
  414. $package->old_short_name = isset($file['info']['old_short_name']) ? $file['info']['old_short_name'] : '';
  415. $package->status = 1;
  416. }
  417. // we only call node save when the title, description changes
  418. // or when it's a new package.
  419. if (!isset($package->nid) ||
  420. (isset($package->title) && ($package->title != $name)) ||
  421. (isset($file['info']['description']) && ($package->description != $file['info']['description'])) ||
  422. (isset($file['info']['old_short_name']) && ($package->old_short_name != $file['info']['old_short_name']))) {
  423. $package->title = $name;
  424. $package->description = isset($file['info']['description']) ? $file['info']['description'] : '';
  425. $package->old_short_name = isset($file['info']['old_short_name']) ? $file['info']['old_short_name'] : '';
  426. node_save($package);
  427. }
  428. $data[$plural][$short_name]['package_id'] = $package->nid;
  429. }
  430. }
  431. }
  432. /**
  433. * Implements hook_views_api().
  434. */
  435. function hosting_package_views_api() {
  436. return array(
  437. 'api' => 3,
  438. 'path' => drupal_get_path('module', 'hosting_package') . '/includes/views',
  439. );
  440. }
  441. /**
  442. * Control block visibility.
  443. */
  444. function hosting_package_block_visibility() {
  445. $node = menu_get_object();
  446. if (!empty($node)) {
  447. return $node->type == 'package' && $node->package_type != 'profile';
  448. }
  449. }