maynard-malone/core-bundle

This package is abandoned and no longer maintained. No replacement package was suggested.
There is no license information available for the latest version (dev-master) of this package.

Maynard Malone's Core Bundle

dev-master 2015-08-13 15:40 UTC

README

This bundle provides various tools to rapidly develop applications with Symfony2.

Note: This is a work-in-progress, and not currently intended for public use (although you're more than welcome to).

It provides the common functionality leveraged at Maynard Malone used throughout our Symfony2 based web applications such as:

  • Simple interfaces to various social media APIs.
  • Event-based JavaScript variable exposure.
  • Cron system with Sonata Admin integration allowing for periodic execution of Symfony console commands.

Installation

Download the bundle

From the command line, browse to your project's root directory and execute:

$ composer require "maynard-malone/core-bundle" "dev-master"

Enable the bundle

// app/AppKernel.php
public function registerBundles()
{
    return array(
        // ...
        new MaynardMalone\CoreBundle\MaynardMaloneCoreBundle(),
    );
}

Usage

Social media API clients

The creation of social media API clients is simplified through configuration of the bundle. Each client is separate from each other including the Guzzle client used internally.

Creating a client

# app/config.yml
maynard_malone_core:
  twitter:
  clients:
    example:
      access_token: %twitter_access_token% # Token from parameter or similar.
      cache:
        adapter: memcached # Sonata Cache adapter.
        ttls:
          statuses/user_timeline: 60      

Obtaining a client

Option A: Directly from the pool
use MaynardMalone\CoreBundle\Model\Twitter\Enum\DataType;

public function twitterProxyAction($user) {
  $client = $this->get('mm.core.twitter.client_pool')->get('example');

  // ...
}
Option B: Wrap with a service
# services.yml

services:
  # ...

 vendor.twitter_client:
   class: MaynardMalone\CoreBundle\Service\Twitter\TwitterClient
   factory: [ @mm.core.twitter.client_pool, get ]
   arguments: [ example ]
use MaynardMalone\CoreBundle\Model\Twitter\Enum\DataType;

public function twitterProxyAction($user) {
  $client = $this->get('vendor.twitter_client');

  // ...
}

Client HTTP configuration

HTTP configuration can be configured either globally for all HTTP related services in the bundle, or overridden per client.

maynard_malone_core:
  # ...
  http:
    tcp_nodelay: true
    timeout: 5000

    proxy:
      host: 127.0.0.1
      port: 8080

  instagram:
    clients:
      example:
        # ...
        http:
          # tcp_nodelay setting will go back to default of false.
          timeout: 20000
          proxy:
            enabled: false

Exposing variables through to JavaScript

A MaynardMalone\CoreBundle\Event\JsConfigExposureEvent is dispatched through the central Symfony event dispatcher as event name MaynardMalone\CoreBundle\Event\Events::JS_CONFIG_EXPOSURE when the Twig function js_expose_config is called.

By default this is part of the MaynardMaloneCoreBundle::layout.html.twig template as part of the foot_script block prior to all scripts.

This event provides the ability to set/remove data, which will then be exposed to JavaScript as a global object.

The methods delegate to a PropertyAccessor, allowing for nested elements to be set.

use MaynardMalone\CoreBundle\Event\JsConfigExposureEvent;

public function onJsConfigExposure(JSConfigExposureEvent $event) {
  $event->set('[i18n][form][validation_error]', 'Please check the errors below.');

  $event->setMulti(
    array(
      '[i18n][form][modal][confirmation]' => 'Thanks for entering.',
      '[locale]' => 'en',
    )
  );
}

By default, the values are exposed as the global ExposedConfig object.

The above would produce:

var ExposedConfig = {
  i18n: {
    form: {
      validation_error: 'Please check the errors below.',
      modal: {
        confirmation: {
          'Thanks for entering.'
        }
      }
    },
  },
  locale: 'en'
};

Asset management

Support for integration with an independent front-end workflow is provided (e.g. Grunt/Gulp).

It is assumed that two representations of the applications assets are used, one for production (e.g. minified and concatenated) and one for development (e.g. unminifed, individual files). However, for all intents and purposes these are simply two different sets of assets and nothing ties the two together or sets assumptions on how they are created.

A JSON configuration file dictates the paths of the assets for the two environments.

{
  "css": {
    "dev": [
      "css/vendor/library.css",
      "css/app.css"
    ],
    "prod": ["css/all.min.css"]
  },
  "js": {
    "dev": [
      "vendor/jquery.min.js",
      "vendor/respond.min.js",
      "bundles/fosjsrouting/js/router.js",
      "js/app.js"
    ],
    "prod": ["js/all.min.js"]
  }
}

Basic bundle configuration

maynard_malone_core_bundle:
  # ...
  global_assets:
    # Path to assets configuration file
    source: %kernel.root_dir%/config/assets.json

    # Global variable exposed through to Twig
    variable: app_assets 
    web_dir: web 

Twig consumption

The base layout.html.twig template automates integration with the asset management.

{% set css_assets = app.debug ? app_assets.css.dev : app_assets.css.prod %}

{% for asset in css_assets %}
  <link type="text/css" rel="stylesheet" href="{{ asset(asset) }}"/>
{% endfor %}

Cache busting

By enabling cache busting the paths of the production assets will be rewritten to include a cache buster.

For example, if your workflow outputs the production CSS as all.min.<sha1>.css, you can configure such:

maynard_malone_core:
  # ...

  global_assets:
    cache_busting:
      enabled: true
      asset_pattern: '{file_name}.{buster}.{extension}'

And your CSS assets configuration as:

{ 
  "css": {
    "dev": [
      "css/vendor/library.css",
      "css/foo.css",
      "css/bar.css
    ],
    "prod": ["css/all.min.css"]
  }
}

During container compilation files matching the asset pattern (e.g. all.min.*.css in this case) will be searched for, and those exposed through to Twig instead.