Merge pull request #3179 from webpartners/master
[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 * Class constructor, sets name and namespace (those are stored
102 * in the component registry (database) and no need to duplicate
103 * them here, as well as populates the info variable.
104 *
105 * @param string $name name of the component
106 * @param string $namespace namespace prefix for component's files
107 * @access public
108 *
109 */
110 /**
111 * @param $name
112 * @param $namespace
113 * @param $componentID
114 */
115 public function __construct($name, $namespace, $componentID) {
116 $this->name = $name;
117 $this->namespace = $namespace;
118 $this->componentID = $componentID;
119 $this->info = $this->getInfo();
120 $this->info['url'] = $this->getKeyword();
121 }
122
123 /**
124 * EXPERIMENTAL: Get a list of AngularJS modules
125 *
126 * @return array list of modules; same format as CRM_Utils_Hook::angularModules(&$angularModules)
127 * @see CRM_Utils_Hook::angularModules
128 */
129 public function getAngularModules() {
130 return array();
131 }
132
133 /**
134 * Provides base information about the component.
135 * Needs to be implemented in component's information
136 * class.
137 *
138 * @return array collection of required component settings
139 * @access public
140 *
141 */
142 abstract public function getInfo();
143
144 /**
145 * Get a list of entities to register via API
146 *
147 * @return array list of entities; same format as CRM_Utils_Hook::managedEntities(&$entities)
148 * @see CRM_Utils_Hook::managedEntities
149 */
150 public function getManagedEntities() {
151 return array();
152 }
153
154 /**
155 * Provides permissions that are unwise for Anonymous Roles to have
156 *
157 * @return array list of permissions
158 * @see CRM_Component_Info::getPermissions
159 */
160 public function getAnonymousPermissionWarnings() {
161 return array();
162 }
163
164 /**
165 * Provides permissions that are used by component.
166 * Needs to be implemented in component's information
167 * class.
168 *
169 * NOTE: if using conditionally permission return,
170 * implementation of $getAllUnconditionally is required.
171 *
172 * @param bool $getAllUnconditionally
173 *
174 * @return array|null collection of permissions, null if none
175 * @access public
176 */
177 abstract public function getPermissions($getAllUnconditionally = FALSE);
178
179 /**
180 * Determine how many other records refer to a given record
181 *
182 * @param CRM_Core_DAO $dao the item for which we want a reference count
183 * @return array each item in the array is an array with keys:
184 * - name: string, eg "sql:civicrm_email:contact_id"
185 * - type: string, eg "sql"
186 * - count: int, eg "5" if there are 5 email addresses that refer to $dao
187 */
188 public function getReferenceCounts($dao) {
189 return array();
190 }
191
192 /**
193 * Provides information about user dashboard element
194 * offered by this component.
195 *
196 * @return array|null collection of required dashboard settings,
197 * null if no element offered
198 * @access public
199 *
200 */
201 abstract public function getUserDashboardElement();
202
203 /**
204 * Provides information about user dashboard element
205 * offered by this component.
206 *
207 * @return array|null collection of required dashboard settings,
208 * null if no element offered
209 * @access public
210 *
211 */
212 abstract public function registerTab();
213
214 /**
215 * Provides information about advanced search pane
216 * offered by this component.
217 *
218 * @return array|null collection of required pane settings,
219 * null if no element offered
220 * @access public
221 *
222 */
223 abstract public function registerAdvancedSearchPane();
224
225 /**
226 * Provides potential activity types that this
227 * component might want to register in activity history.
228 * Needs to be implemented in component's information
229 * class.
230 *
231 * @return array|null collection of activity types
232 * @access public
233 *
234 */
235 abstract public function getActivityTypes();
236
237 /**
238 * Provides information whether given component is currently
239 * marked as enabled in configuration.
240 *
241 * @return boolean true if component is enabled, false if not
242 * @access public
243 *
244 */
245 public function isEnabled() {
246 $config = CRM_Core_Config::singleton();
247 if (in_array($this->info['name'], $config->enableComponents)) {
248 return TRUE;
249 }
250 return FALSE;
251 }
252
253 /**
254 * Provides component's configuration object.
255 *
256 * @return mixed component's configuration object
257 * @access public
258 *
259 */
260 public function getConfigObject() {
261 return $this->_instantiate(self::COMPONENT_CONFIG_CLASS);
262 }
263
264 /**
265 * Provides component's menu definition object.
266 *
267 * @return mixed component's menu definition object
268 * @access public
269 *
270 */
271 public function getMenuObject() {
272 return $this->_instantiate(self::COMPONENT_MENU_CLASS);
273 }
274
275 /**
276 * Provides component's invocation object.
277 *
278 * @return mixed component's invocation object
279 * @access public
280 *
281 */
282 public function getInvokeObject() {
283 return $this->_instantiate(self::COMPONENT_INVOKE_CLASS);
284 }
285
286 /**
287 * Provides component's BAO Query object.
288 *
289 * @return mixed component's BAO Query object
290 * @access public
291 *
292 */
293 public function getBAOQueryObject() {
294 return $this->_instantiate(self::COMPONENT_BAO_QUERY_CLASS);
295 }
296
297 /**
298 * Builds advanced search form's component specific pane.
299 *
300 * @access public
301 *
302 */
303 public function buildAdvancedSearchPaneForm(&$form) {
304 $bao = $this->getBAOQueryObject();
305 $bao->buildSearchForm($form);
306 }
307
308 /**
309 * Provides component's user dashboard page object.
310 *
311 * @return mixed component's User Dashboard applet object
312 * @access public
313 *
314 */
315 public function getUserDashboardObject() {
316 return $this->_instantiate(self::COMPONENT_USERDASHBOARD_CLASS);
317 }
318
319 /**
320 * Provides component's contact record tab object.
321 *
322 * @return mixed component's contact record tab object
323 * @access public
324 *
325 */
326 public function getTabObject() {
327 return $this->_instantiate(self::COMPONENT_TAB_CLASS);
328 }
329
330 /**
331 * Provides component's advanced search pane's template path.
332 *
333 * @return string component's advanced search pane's template path
334 * @access public
335 *
336 */
337 public function getAdvancedSearchPaneTemplatePath() {
338 $fullpath = $this->namespace . '_' . self::COMPONENT_ADVSEARCHPANE_CLASS;
339 return str_replace('_', DIRECTORY_SEPARATOR, $fullpath . '.tpl');
340 }
341
342 /**
343 * Provides information whether given component uses system wide search.
344 *
345 * @return boolean true if component needs search integration
346 * @access public
347 *
348 */
349 public function usesSearch() {
350 return $this->info['search'] ? TRUE : FALSE;
351 }
352
353 /**
354 * Provides the xml menu files
355 *
356 * @return array array of menu files
357 * @access public
358 *
359 */
360 public function menuFiles() {
361 return CRM_Utils_File::getFilesByExtension($this->_getMenuXMLPath(), 'xml');
362 }
363
364 /**
365 * Simple "keyword" getter.
366 * FIXME: It should be protected so the keyword is not
367 * FIXME: accessed from beyond component infrastructure.
368 *
369 * @return string component keyword
370 * @access public
371 *
372 */
373 public function getKeyword() {
374 return $this->keyword;
375 }
376
377 /**
378 * Helper for figuring out menu XML file location.
379 *
380 * @return mixed component's element as class instance
381 * @access private
382 *
383 */
384 private function _getMenuXMLPath() {
385 global $civicrm_root;
386 $fullpath = $this->namespace . '_' . self::COMPONENT_XML_RESOURCES . '_' . self::COMPONENT_MENU_XML;
387 return CRM_Utils_File::addTrailingSlash($civicrm_root . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $fullpath));
388 }
389
390 /**
391 * Helper for instantiating component's elements.
392 *
393 * @param $cl
394 *
395 * @return mixed component's element as class instance
396 * @access private
397 */
398 private function _instantiate($cl) {
399 $className = $this->namespace . '_' . $cl;
400 require_once (str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php');
401 return new $className();
402 }
403 }
404