CRM-20981 - Move crmApp init from `Page\Main::run()` to `AngularLoader::useApp()`
authorTim Otten <totten@civicrm.org>
Sat, 29 Jul 2017 00:01:10 +0000 (17:01 -0700)
committerTim Otten <totten@civicrm.org>
Sat, 29 Jul 2017 00:18:48 +0000 (17:18 -0700)
Civi/Angular/AngularLoader.php
Civi/Angular/Page/Main.php

index bf18b306974ebc982ce281b149427539c4444217..80cd4906e7e3b9bb4f0e7c1bd1ce612a063bd917 100644 (file)
@@ -61,6 +61,11 @@ class AngularLoader {
    */
   protected $modules;
 
+  /**
+   * @var array|NULL
+   */
+  protected $crmApp = NULL;
+
   /**
    * AngularLoader constructor.
    */
@@ -81,6 +86,25 @@ class AngularLoader {
     $angular = $this->getAngular();
     $res = $this->getRes();
 
+    if ($this->crmApp !== NULL) {
+      $this->addModules($this->crmApp['modules']);
+      $region = \CRM_Core_Region::instance($this->crmApp['region']);
+      $region->update('default', array('disabled' => TRUE));
+      $region->add(array('template' => $this->crmApp['file'], 'weight' => 0));
+      $this->res->addSetting(array(
+        'crmApp' => array(
+          'defaultRoute' => $this->crmApp['defaultRoute'],
+        ),
+      ));
+
+      // If trying to load an Angular page via AJAX, the route must be passed as a
+      // URL parameter, since the server doesn't receive information about
+      // URL fragments (i.e, what comes after the #).
+      $this->res->addSetting(array(
+        'angularRoute' => $this->crmApp['activeRoute'],
+      ));
+    }
+
     $moduleNames = $this->findActiveModules();
     if (!$this->isAllModules($moduleNames)) {
       $assetParams = array('modules' => implode(',', $moduleNames));
@@ -141,6 +165,40 @@ class AngularLoader {
     return $this;
   }
 
+  /**
+   * Use Civi's generic "application" module.
+   *
+   * This is suitable for use on a basic, standalone Angular page
+   * like `civicrm/a`. (If you need to integrate Angular with pre-existing,
+   * non-Angular pages... then this probably won't help.)
+   *
+   * The Angular bootstrap process requires an HTML directive like
+   * `<div ng-app="foo">`.
+   *
+   * Calling useApp() will replace the page's main body with the
+   * `<div ng-app="crmApp">...</div>` and apply some configuration options
+   * for the `crmApp` module.
+   *
+   * @param array $settings
+   *   A list of settings. Accepted values:
+   *    - activeRoute: string, the route to open up immediately
+   *    - defaultRoute: string, use this to redirect the default route to another page
+   *    - region: string, the place on the page where we should insert the angular app
+   * @return AngularLoader
+   * @link https://code.angularjs.org/1.5.11/docs/guide/bootstrap
+   */
+  public function useApp($settings = array()) {
+    $defaults = array(
+      'modules' => array('crmApp'),
+      'activeRoute' => NULL,
+      'defaultRoute' => NULL,
+      'region' => 'page-body',
+      'file' => 'Civi/Angular/Page/Main.tpl',
+    );
+    $this->crmApp = array_merge($defaults, $settings);
+    return $this;
+  }
+
   /**
    * Get a list of all Angular modules which should be activated on this
    * page.
index a13a18c0682cd50f70f95f542fd91c93013f17a9..aa31fef7112d16ab89827d56f20384ace0609a14 100644 (file)
@@ -76,25 +76,12 @@ class Main extends \CRM_Core_Page {
   public function registerResources() {
     $loader = new \Civi\Angular\AngularLoader();
     $loader->setPageName('civicrm/a');
-    $loader->setModules(array('crmApp'));
-    $loader->load();
-
-    // If trying to load an Angular page via AJAX, the route must be passed as a
-    // URL parameter, since the server doesn't receive information about
-    // URL fragments (i.e, what comes after the #).
-    \CRM_Core_Resources::singleton()->addSetting(array(
-      'crmApp' => array(
-        'defaultRoute' => NULL,
-      ),
-      'angularRoute' => \CRM_Utils_Request::retrieve('route', 'String'),
+    $loader->useApp(array(
+      'activeRoute' => \CRM_Utils_Request::retrieve('route', 'String'),
+      'defaultRoute' => NULL,
     ));
-  }
+    $loader->load();
 
-  /**
-   * @inheritdoc
-   */
-  public function getTemplateFileName() {
-    return 'Civi/Angular/Page/Main.tpl';
   }
 
 }