Merge branch '4.5' of https://github.com/civicrm/civicrm-core
[civicrm-core.git] / CRM / Core / Component / Info.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * This interface defines methods that need to be implemented
30 * for a component to introduce itself to the system.
31 *
32 * @package CRM
33 * @copyright CiviCRM LLC (c) 2004-2014
34 * $Id$
35 *
36 */
37
38 abstract class CRM_Core_Component_Info {
39
40 /**
41 * Name of the class (minus component namespace path)
42 * of the component invocation class'es name.
43 */
44 CONST COMPONENT_INVOKE_CLASS = 'Invoke';
45
46 /**
47 * Name of the class (minus component namespace path)
48 * of the component configuration class'es name.
49 */
50 CONST COMPONENT_CONFIG_CLASS = 'Config';
51
52 /**
53 * Name of the class (minus component namespace path)
54 * of the component BAO Query class'es name.
55 */
56 CONST COMPONENT_BAO_QUERY_CLASS = 'BAO_Query';
57
58 /**
59 * Name of the class (minus component namespace path)
60 * of the component user dashboard plugin.
61 */
62 CONST COMPONENT_USERDASHBOARD_CLASS = 'Page_UserDashboard';
63
64 /**
65 * Name of the class (minus component namespace path)
66 * of the component tab offered to contact record view.
67 */
68 CONST COMPONENT_TAB_CLASS = 'Page_Tab';
69
70 /**
71 * Name of the class (minus component namespace path)
72 * of the component tab offered to contact record view.
73 */
74 CONST COMPONENT_ADVSEARCHPANE_CLASS = 'Form_Search_AdvancedSearchPane';
75
76 /**
77 * Name of the directory (assumed in component directory)
78 * where xml resources used by this component live.
79 */
80 CONST COMPONENT_XML_RESOURCES = 'xml';
81
82 /**
83 * Name of the directory (assumed in xml resources path)
84 * containing component menu definition XML file names.
85 */
86 CONST COMPONENT_MENU_XML = 'Menu';
87
88 /**
89 * Stores component information.
90 * @var array component settings as key/value pairs
91 */
92 public $info;
93
94 /*
95 * Stores component keyword
96 * @var string name of component keyword
97 */
98 protected $keyword;
99
100 /**
101 * @param string $name name of the component
102 * @param string $namespace namespace prefix for component's files
103 * @param int $componentID
104 */
105 public function __construct($name, $namespace, $componentID) {
106 $this->name = $name;
107 $this->namespace = $namespace;
108 $this->componentID = $componentID;
109 $this->info = $this->getInfo();
110 $this->info['url'] = $this->getKeyword();
111 }
112
113 /**
114 * EXPERIMENTAL: Get a list of AngularJS modules
115 *
116 * @return array list of modules; same format as CRM_Utils_Hook::angularModules(&$angularModules)
117 * @see CRM_Utils_Hook::angularModules
118 */
119 public function getAngularModules() {
120 return array();
121 }
122
123 /**
124 * Provides base information about the component.
125 * Needs to be implemented in component's information
126 * class.
127 *
128 * @return array collection of required component settings
129 * @access public
130 *
131 */
132 abstract public function getInfo();
133
134 /**
135 * Get a list of entities to register via API
136 *
137 * @return array list of entities; same format as CRM_Utils_Hook::managedEntities(&$entities)
138 * @see CRM_Utils_Hook::managedEntities
139 */
140 public function getManagedEntities() {
141 return array();
142 }
143
144 /**
145 * Provides permissions that are unwise for Anonymous Roles to have
146 *
147 * @return array list of permissions
148 * @see CRM_Component_Info::getPermissions
149 */
150 public function getAnonymousPermissionWarnings() {
151 return array();
152 }
153
154 /**
155 * Provides permissions that are used by component.
156 * Needs to be implemented in component's information
157 * class.
158 *
159 * NOTE: if using conditionally permission return,
160 * implementation of $getAllUnconditionally is required.
161 *
162 * @param bool $getAllUnconditionally
163 *
164 * @return array|null collection of permissions, null if none
165 * @access public
166 */
167 abstract public function getPermissions($getAllUnconditionally = FALSE);
168
169 /**
170 * Determine how many other records refer to a given record
171 *
172 * @param CRM_Core_DAO $dao the item for which we want a reference count
173 * @return array each item in the array is an array with keys:
174 * - name: string, eg "sql:civicrm_email:contact_id"
175 * - type: string, eg "sql"
176 * - count: int, eg "5" if there are 5 email addresses that refer to $dao
177 */
178 public function getReferenceCounts($dao) {
179 return array();
180 }
181
182 /**
183 * Provides information about user dashboard element
184 * offered by this component.
185 *
186 * @return array|null collection of required dashboard settings,
187 * null if no element offered
188 * @access public
189 *
190 */
191 abstract public function getUserDashboardElement();
192
193 /**
194 * Provides information about user dashboard element
195 * offered by this component.
196 *
197 * @return array|null collection of required dashboard settings,
198 * null if no element offered
199 * @access public
200 *
201 */
202 abstract public function registerTab();
203
204 /**
205 * Provides information about advanced search pane
206 * offered by this component.
207 *
208 * @return array|null collection of required pane settings,
209 * null if no element offered
210 * @access public
211 *
212 */
213 abstract public function registerAdvancedSearchPane();
214
215 /**
216 * Provides potential activity types that this
217 * component might want to register in activity history.
218 * Needs to be implemented in component's information
219 * class.
220 *
221 * @return array|null collection of activity types
222 * @access public
223 *
224 */
225 abstract public function getActivityTypes();
226
227 /**
228 * Provides information whether given component is currently
229 * marked as enabled in configuration.
230 *
231 * @return boolean true if component is enabled, false if not
232 * @access public
233 *
234 */
235 public function isEnabled() {
236 $config = CRM_Core_Config::singleton();
237 if (in_array($this->info['name'], $config->enableComponents)) {
238 return TRUE;
239 }
240 return FALSE;
241 }
242
243 /**
244 * Provides component's configuration object.
245 *
246 * @return mixed component's configuration object
247 * @access public
248 *
249 */
250 public function getConfigObject() {
251 return $this->_instantiate(self::COMPONENT_CONFIG_CLASS);
252 }
253
254 /**
255 * Provides component's menu definition object.
256 *
257 * @return mixed component's menu definition object
258 * @access public
259 *
260 */
261 public function getMenuObject() {
262 return $this->_instantiate(self::COMPONENT_MENU_CLASS);
263 }
264
265 /**
266 * Provides component's invocation object.
267 *
268 * @return mixed component's invocation object
269 * @access public
270 *
271 */
272 public function getInvokeObject() {
273 return $this->_instantiate(self::COMPONENT_INVOKE_CLASS);
274 }
275
276 /**
277 * Provides component's BAO Query object.
278 *
279 * @return mixed component's BAO Query object
280 * @access public
281 *
282 */
283 public function getBAOQueryObject() {
284 return $this->_instantiate(self::COMPONENT_BAO_QUERY_CLASS);
285 }
286
287 /**
288 * Builds advanced search form's component specific pane.
289 *
290 * @access public
291 *
292 */
293 public function buildAdvancedSearchPaneForm(&$form) {
294 $bao = $this->getBAOQueryObject();
295 $bao->buildSearchForm($form);
296 }
297
298 /**
299 * Provides component's user dashboard page object.
300 *
301 * @return mixed component's User Dashboard applet object
302 * @access public
303 *
304 */
305 public function getUserDashboardObject() {
306 return $this->_instantiate(self::COMPONENT_USERDASHBOARD_CLASS);
307 }
308
309 /**
310 * Provides component's contact record tab object.
311 *
312 * @return mixed component's contact record tab object
313 * @access public
314 *
315 */
316 public function getTabObject() {
317 return $this->_instantiate(self::COMPONENT_TAB_CLASS);
318 }
319
320 /**
321 * Provides component's advanced search pane's template path.
322 *
323 * @return string component's advanced search pane's template path
324 * @access public
325 *
326 */
327 public function getAdvancedSearchPaneTemplatePath() {
328 $fullpath = $this->namespace . '_' . self::COMPONENT_ADVSEARCHPANE_CLASS;
329 return str_replace('_', DIRECTORY_SEPARATOR, $fullpath . '.tpl');
330 }
331
332 /**
333 * Provides information whether given component uses system wide search.
334 *
335 * @return boolean true if component needs search integration
336 * @access public
337 *
338 */
339 public function usesSearch() {
340 return $this->info['search'] ? TRUE : FALSE;
341 }
342
343 /**
344 * Provides the xml menu files
345 *
346 * @return array array of menu files
347 * @access public
348 *
349 */
350 public function menuFiles() {
351 return CRM_Utils_File::getFilesByExtension($this->_getMenuXMLPath(), 'xml');
352 }
353
354 /**
355 * Simple "keyword" getter.
356 * FIXME: It should be protected so the keyword is not
357 * FIXME: accessed from beyond component infrastructure.
358 *
359 * @return string component keyword
360 * @access public
361 *
362 */
363 public function getKeyword() {
364 return $this->keyword;
365 }
366
367 /**
368 * Helper for figuring out menu XML file location.
369 *
370 * @return mixed component's element as class instance
371 * @access private
372 *
373 */
374 private function _getMenuXMLPath() {
375 global $civicrm_root;
376 $fullpath = $this->namespace . '_' . self::COMPONENT_XML_RESOURCES . '_' . self::COMPONENT_MENU_XML;
377 return CRM_Utils_File::addTrailingSlash($civicrm_root . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $fullpath));
378 }
379
380 /**
381 * Helper for instantiating component's elements.
382 *
383 * @param $cl
384 *
385 * @return mixed component's element as class instance
386 * @access private
387 */
388 private function _instantiate($cl) {
389 $className = $this->namespace . '_' . $cl;
390 require_once (str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php');
391 return new $className();
392 }
393 }
394