3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * Defines a simple implementation of a drupal block.
21 * Blocks definitions and html are in a smarty template file.
23 class CRM_Core_Block
{
26 * The following blocks are supported.
40 * Template file names for the above blocks.
43 public static $_properties = NULL;
48 public function __construct() {
52 * Initialises the $_properties array
54 public static function initProperties() {
55 if (!defined('BLOCK_CACHE_GLOBAL')) {
56 define('BLOCK_CACHE_GLOBAL', 0x0008);
59 if (!defined('BLOCK_CACHE_PER_PAGE')) {
60 define('BLOCK_CACHE_PER_PAGE', 0x0004);
63 if (!defined('BLOCK_NO_CACHE')) {
64 define('BLOCK_NO_CACHE', -1);
67 if (!(self
::$_properties)) {
68 $config = CRM_Core_Config
::singleton();
69 self
::$_properties = array(
70 // set status item to 0 to disable block by default (at install)
71 self
::CREATE_NEW
=> array(
72 'template' => 'CreateNew.tpl',
73 'info' => ts('CiviCRM Create New Record'),
76 'cache' => BLOCK_CACHE_GLOBAL
,
80 'pages' => "civicrm\ncivicrm/*",
81 'region' => $config->userSystem
->getDefaultBlockLocation(),
83 self
::RECENTLY_VIEWED
=> array(
84 'template' => 'RecentlyViewed.tpl',
85 'info' => ts('CiviCRM Recent Items'),
86 'subject' => ts('Recent Items'),
88 'cache' => BLOCK_NO_CACHE
,
92 'pages' => "civicrm\ncivicrm/*",
93 'region' => $config->userSystem
->getDefaultBlockLocation(),
95 self
::DASHBOARD
=> array(
96 'template' => 'Dashboard.tpl',
97 'info' => ts('CiviCRM Contact Dashboard'),
100 'cache' => BLOCK_NO_CACHE
,
104 'pages' => "civicrm\ncivicrm/*",
105 'region' => $config->userSystem
->getDefaultBlockLocation(),
108 'template' => 'Add.tpl',
109 'info' => ts('CiviCRM Quick Add'),
110 'subject' => ts('New Individual'),
112 'cache' => BLOCK_NO_CACHE
,
116 'pages' => "civicrm\ncivicrm/*",
117 'region' => $config->userSystem
->getDefaultBlockLocation(),
119 self
::LANGSWITCH
=> array(
120 'template' => 'LangSwitch.tpl',
121 'info' => ts('CiviCRM Language Switcher'),
123 'templateValues' => array(),
125 'cache' => BLOCK_NO_CACHE
,
129 'pages' => "civicrm\ncivicrm/*",
130 'region' => $config->userSystem
->getDefaultBlockLocation(),
132 self
::EVENT
=> array(
133 'template' => 'Event.tpl',
134 'info' => ts('CiviCRM Upcoming Events'),
135 'subject' => ts('Upcoming Events'),
136 'templateValues' => array(),
138 'cache' => BLOCK_NO_CACHE
,
142 'pages' => "civicrm\ncivicrm/*",
143 'region' => $config->userSystem
->getDefaultBlockLocation(),
145 self
::FULLTEXT_SEARCH
=> array(
146 'template' => 'FullTextSearch.tpl',
147 'info' => ts('CiviCRM Full-text Search'),
148 'subject' => ts('Full-text Search'),
150 'cache' => BLOCK_NO_CACHE
,
154 'pages' => "civicrm\ncivicrm/*",
155 'region' => $config->userSystem
->getDefaultBlockLocation(),
159 ksort(self
::$_properties);
164 * Returns the desired property from the $_properties array
167 * One of the class constants (ADD, SEARCH, etc.).
168 * @param string $property
169 * The desired property.
172 * the value of the desired property
174 public static function getProperty($id, $property) {
175 if (!(self
::$_properties)) {
176 self
::initProperties();
178 return self
::$_properties[$id][$property] ??
NULL;
182 * Sets the desired property in the $_properties array
185 * One of the class constants (ADD, SEARCH, etc.).
186 * @param string $property
187 * The desired property.
188 * @param string $value
189 * The value of the desired property.
191 public static function setProperty($id, $property, $value) {
192 if (!(self
::$_properties)) {
193 self
::initProperties();
195 self
::$_properties[$id][$property] = $value;
199 * Returns the whole $_properties array.
202 * the $_properties array
204 public static function properties() {
205 if (!(self
::$_properties)) {
206 self
::initProperties();
208 return self
::$_properties;
212 * Creates the info block for drupal.
216 public static function getInfo() {
219 foreach (self
::properties() as $id => $value) {
220 if ($value['active']) {
221 if (in_array($id, array(
226 if (!CRM_Core_Permission
::check('add contacts') &&
227 !CRM_Core_Permission
::check('edit groups')
231 //validate across edit/view - CRM-5666
232 if ($hasAccess && ($id == self
::ADD
)) {
233 $hasAccess = CRM_Core_Permission
::giveMeAllACLs();
240 if ($id == self
::EVENT
&&
241 (!CRM_Core_Permission
::access('CiviEvent', FALSE) ||
242 !CRM_Core_Permission
::check('view event info')
249 'info' => $value['info'],
250 'cache' => $value['cache'],
251 'region' => $value['region'],
252 'visibility' => $value['visibility'],
253 'pages' => $value['pages'],
254 'status' => $value['status'],
255 'weight' => $value['weight'],
264 * Set the post action values for the block.
266 * php is lame and u cannot call functions from static initializers
271 private static function setTemplateValues($id) {
273 case self
::CREATE_NEW
:
274 self
::setTemplateShortcutValues();
277 case self
::DASHBOARD
:
278 self
::setTemplateDashboardValues();
282 $defaultLocation = CRM_Core_BAO_LocationType
::getDefault();
283 $defaultPrimaryLocationId = $defaultLocation->id
;
285 'postURL' => CRM_Utils_System
::url('civicrm/contact/add', 'reset=1&ct=Individual'),
286 'primaryLocationType' => $defaultPrimaryLocationId,
289 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
290 $values[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
293 self
::setProperty(self
::ADD
,
299 case self
::LANGSWITCH
:
300 // gives the currentPath without trailing empty lcMessages to be completed
301 $values = array('queryString' => CRM_Utils_System
::getLinksUrl('lcMessages', TRUE, FALSE, FALSE));
302 self
::setProperty(self
::LANGSWITCH
, 'templateValues', $values);
305 case self
::FULLTEXT_SEARCH
:
307 'fullTextSearchID' => CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_OptionValue',
308 'CRM_Contact_Form_Search_Custom_FullText', 'value', 'name'
311 self
::setProperty(self
::FULLTEXT_SEARCH
, 'templateValues', $urlArray);
314 case self
::RECENTLY_VIEWED
:
315 $recent = CRM_Utils_Recent
::get();
316 self
::setProperty(self
::RECENTLY_VIEWED
, 'templateValues', array('recentlyViewed' => $recent));
320 self
::setTemplateEventValues();
326 * Create the list of options to create New objects for the application and format is as a block.
328 private static function setTemplateShortcutValues() {
329 $config = CRM_Core_Config
::singleton();
331 static $shortCuts = array();
334 if (CRM_Core_Permission
::check('add contacts')) {
335 if (CRM_Core_Permission
::giveMeAllACLs()) {
336 $shortCuts = CRM_Contact_BAO_ContactType
::getCreateNewList();
340 // new activity (select target contact)
341 $shortCuts = array_merge($shortCuts, array(
343 'path' => 'civicrm/activity',
344 'query' => 'action=add&reset=1&context=standalone',
345 'ref' => 'new-activity',
346 'title' => ts('Activity'),
350 $components = CRM_Core_Component
::getEnabledComponents();
352 if (!empty($config->enableComponents
)) {
353 // check if we can process credit card contribs
354 $newCredit = CRM_Core_Config
::isEnabledBackOfficeCreditCardPayments();
356 foreach ($components as $componentName => $obj) {
357 if (in_array($componentName, $config->enableComponents
)) {
358 $obj->creatNewShortcut($shortCuts, $newCredit);
363 // new email (select recipients)
364 $shortCuts = array_merge($shortCuts, array(
366 'path' => 'civicrm/activity/email/add',
367 'query' => 'atype=3&action=add&reset=1&context=standalone',
368 'ref' => 'new-email',
369 'title' => ts('Email'),
373 if (CRM_Core_Permission
::check('edit groups')) {
374 $shortCuts = array_merge($shortCuts, array(
376 'path' => 'civicrm/group/add',
377 'query' => 'reset=1',
378 'ref' => 'new-group',
379 'title' => ts('Group'),
384 if (CRM_Core_Permission
::check('manage tags')) {
385 $shortCuts = array_merge($shortCuts, array(
387 'path' => 'civicrm/tag',
388 'query' => 'reset=1&action=add',
390 'title' => ts('Tag'),
395 if (empty($shortCuts)) {
401 foreach ($shortCuts as $key => $short) {
402 $values[$key] = self
::setShortCutValues($short);
405 // Deprecated hook with typo. Please don't use this!
406 CRM_Utils_Hook
::links('create.new.shorcuts',
408 CRM_Core_DAO
::$_nullObject,
412 // Hook that enables extensions to add user-defined links
413 CRM_Utils_Hook
::links('create.new.shortcuts',
415 CRM_Core_DAO
::$_nullObject,
419 foreach ($values as $key => $val) {
420 if (!empty($val['title'])) {
421 $values[$key]['name'] = CRM_Utils_Array
::value('name', $val, $val['title']);
425 self
::setProperty(self
::CREATE_NEW
, 'templateValues', array('shortCuts' => $values));
433 private static function setShortcutValues($short) {
435 if (isset($short['url'])) {
436 $value['url'] = $short['url'];
438 elseif (isset($short['path'])) {
439 $value['url'] = CRM_Utils_System
::url($short['path'], $short['query'], FALSE);
441 $value['title'] = $short['title'];
442 $value['ref'] = $short['ref'] ??
'';
443 if (!empty($short['shortCuts'])) {
444 foreach ($short['shortCuts'] as $shortCut) {
445 $value['shortCuts'][] = self
::setShortcutValues($shortCut);
452 * Create the list of dashboard links.
454 private static function setTemplateDashboardValues() {
455 static $dashboardLinks = array();
456 if (CRM_Core_Permission
::check('access Contact Dashboard')) {
457 $dashboardLinks = array(
459 'path' => 'civicrm/user',
460 'query' => 'reset=1',
461 'title' => ts('My Contact Dashboard'),
466 if (empty($dashboardLinks)) {
471 foreach ($dashboardLinks as $dash) {
473 if (isset($dash['url'])) {
474 $value['url'] = $dash['url'];
477 $value['url'] = CRM_Utils_System
::url($dash['path'], $dash['query'], FALSE);
479 $value['title'] = $dash['title'];
480 $value['key'] = $dash['key'] ??
NULL;
483 self
::setProperty(self
::DASHBOARD
, 'templateValues', array('dashboardLinks' => $values));
487 * Create the list of mail urls for the application and format is as a block.
489 private static function setTemplateMailValues() {
490 static $shortCuts = NULL;
495 'path' => 'civicrm/mailing/send',
496 'query' => 'reset=1',
497 'title' => ts('Send Mailing'),
500 'path' => 'civicrm/mailing/browse',
501 'query' => 'reset=1',
502 'title' => ts('Browse Sent Mailings'),
508 foreach ($shortCuts as $short) {
510 $value['url'] = CRM_Utils_System
::url($short['path'], $short['query']);
511 $value['title'] = $short['title'];
514 self
::setProperty(self
::MAIL
, 'templateValues', array('shortCuts' => $values));
518 * Create the event blocks for upcoming events.
520 private static function setTemplateEventValues() {
521 $config = CRM_Core_Config
::singleton();
523 $info = CRM_Event_BAO_Event
::getCompleteInfo(date("Ymd"));
526 $session = CRM_Core_Session
::singleton();
527 // check if registration link should be displayed
528 foreach ($info as $id => $event) {
529 //@todo FIXME - validRegistraionRequest takes eventID not contactID as a param
530 // this is called via an obscure patch from Joomla event block rendering (only)
531 $info[$id]['onlineRegistration'] = CRM_Event_BAO_Event
::validRegistrationRequest($event,
532 $session->get('userID')
536 self
::setProperty(self
::EVENT
, 'templateValues', array('eventBlock' => $info));
541 * Given an id creates a subject/content array
548 public static function getContent($id) {
549 // return if upgrade mode
550 $config = CRM_Core_Config
::singleton();
551 if ($config->isUpgradeMode()) {
555 if (!self
::getProperty($id, 'active')) {
559 if ($id == self
::EVENT
&&
560 CRM_Core_Permission
::check('view event info')
562 // is CiviEvent enabled?
563 if (!CRM_Core_Permission
::access('CiviEvent', FALSE)) {
568 // require 'access CiviCRM' permissons, except for the language switch block
569 elseif (!CRM_Core_Permission
::check('access CiviCRM') && $id != self
::LANGSWITCH
) {
572 elseif ($id == self
::ADD
) {
574 if (!CRM_Core_Permission
::check('add contacts') &&
575 !CRM_Core_Permission
::check('edit groups')
579 //validate across edit/view - CRM-5666
581 $hasAccess = CRM_Core_Permission
::giveMeAllACLs();
588 self
::setTemplateValues($id);
590 // Suppress Recent Items block if it's empty - CRM-5188
591 if ($id == self
::RECENTLY_VIEWED
) {
592 $recent = self
::getProperty($id, 'templateValues');
593 if (CRM_Utils_Array
::crmIsEmptyArray($recent)) {
598 // Suppress Language switcher if language is inherited from CMS - CRM-9971
599 $config = CRM_Core_Config
::singleton();
600 if ($id == self
::LANGSWITCH
&& $config->inheritLocale
) {
605 $block['name'] = 'block-civicrm';
606 $block['id'] = $block['name'] . '_' . $id;
607 $block['subject'] = self
::fetch($id, 'Subject.tpl',
608 array('subject' => self
::getProperty($id, 'subject'))
610 $block['content'] = self
::fetch($id, self
::getProperty($id, 'template'),
611 self
::getProperty($id, 'templateValues')
618 * Given an id and a template, fetch the contents
622 * @param string $fileName
623 * Name of the template file.
624 * @param array $properties
625 * Template variables.
629 public static function fetch($id, $fileName, $properties) {
630 $template = CRM_Core_Smarty
::singleton();
633 $template->assign($properties);
636 return $template->fetch('CRM/Block/' . $fileName);