4 You may buy me a Beer, a Tea or help with Server fees with a paypal donation to
 
   5 the address <paypal@rapsys.eu>.
 
   7 Don't forget to show your love for this project, feel free to report bugs to
 
   8 the author, issues which are security relevant should be disclosed privately
 
  11 Patches are welcomed and grant credit when requested.
 
  16 Applications that use Symfony Flex
 
  17 ----------------------------------
 
  19 Add bundle custom repository to your project's `composer.json` file:
 
  28                                 "name": "rapsys/packbundle",
 
  29                                 "version": "dev-master",
 
  32                                         "url": "https://git.rapsys.eu/packbundle",
 
  37                                                 "Rapsys\\PackBundle\\": ""
 
  41                                         "symfony/asset": "^4.0|^5.0|^6.0|^7.0",
 
  42                                         "symfony/flex": "^1.0|^2.0",
 
  43                                         "symfony/framework-bundle": "^4.0|^5.0|^6.0|^7.0",
 
  44                                         "symfony/process": "^4.0|^5.0|^6.0|^7.0",
 
  45                                         "symfony/twig-bundle": "^4.0|^5.0|^6.0|^7.0"
 
  54 Then open a command console, enter your project directory and execute:
 
  57 $ composer require rapsys/packbundle dev-master
 
  60 Applications that don't use Symfony Flex
 
  61 ----------------------------------------
 
  63 ### Step 1: Download the Bundle
 
  65 Open a command console, enter your project directory and execute the
 
  66 following command to download the latest stable version of this bundle:
 
  69 $ composer require rapsys/packbundle dev-master
 
  72 This command requires you to have Composer installed globally, as explained
 
  73 in the [installation chapter](https://getcomposer.org/doc/00-intro.md)
 
  74 of the Composer documentation.
 
  76 ### Step 2: Enable the Bundle
 
  78 Then, enable the bundle by adding it to the list of registered bundles
 
  79 in the `app/AppKernel.php` file of your project:
 
  86 class AppKernel extends Kernel
 
  88         public function registerBundles()
 
  92                         new Rapsys\PackBundle\RapsysPackBundle(),
 
 102 ### Step 3: Configure the Bundle
 
 104 Setup configuration file `config/packages/rapsys_pack.yaml` with the following
 
 105 content available in `Resources/config/packages/rapsys_pack.yaml`:
 
 108 #Services configuration
 
 110     #Replace assets.packages definition
 
 112         class: 'Symfony\Component\Asset\Packages'
 
 113         arguments: [ '@rapsys_pack.path_package' ]
 
 114     #Replace assets.context definition
 
 116         class: 'Rapsys\PackBundle\Context\RequestStackContext'
 
 117         arguments: [ '@request_stack', '%asset.request_context.base_path%', '%asset.request_context.secure%' ]
 
 118     #Register assets pack package
 
 119     rapsys_pack.path_package:
 
 120         class: 'Rapsys\PackBundle\Package\PathPackage'
 
 121         arguments: [ '/', '@assets.empty_version_strategy', '@assets.context' ]
 
 123     #Register twig pack extension
 
 124     rapsys_pack.pack_extension:
 
 125         class: 'Rapsys\PackBundle\Extension\PackExtension'
 
 126         arguments: [ '@service_container', '@rapsys_pack.intl_util', '@file_locator', '@rapsys_pack.path_package', '@rapsys_pack.slugger_util' ]
 
 127         tags: [ 'twig.extension' ]
 
 128     #Register intl util service
 
 129     rapsys_pack.intl_util:
 
 130         class: 'Rapsys\PackBundle\Util\IntlUtil'
 
 132     #Register facebook event subscriber
 
 133     Rapsys\PackBundle\Subscriber\FacebookSubscriber:
 
 134         arguments: [ '@router', [] ]
 
 135         tags: [ 'kernel.event_subscriber' ]
 
 136     #Register intl util class alias
 
 137     Rapsys\PackBundle\Util\IntlUtil:
 
 138         alias: 'rapsys_pack.intl_util'
 
 139     #Register facebook util service
 
 140     rapsys_pack.facebook_util:
 
 141         class: 'Rapsys\PackBundle\Util\FacebookUtil'
 
 142         arguments: [ '@router', '%kernel.project_dir%/var/cache', '%rapsys_pack.path%' ]
 
 144     #Register facebook util class alias
 
 145     Rapsys\PackBundle\Util\FacebookUtil:
 
 146         alias: 'rapsys_pack.facebook_util'
 
 147     #Register image util service
 
 148     rapsys_pack.image_util:
 
 149         class: 'Rapsys\PackBundle\Util\ImageUtil'
 
 150         arguments: [ '@router', '@rapsys_pack.slugger_util', '%kernel.project_dir%/var/cache', '%rapsys_pack.path%' ]
 
 152     #Register image util class alias
 
 153     Rapsys\PackBundle\Util\ImageUtil:
 
 154         alias: 'rapsys_pack.image_util'
 
 155     #Register map util service
 
 156     rapsys_pack.map_util:
 
 157         class: 'Rapsys\PackBundle\Util\MapUtil'
 
 158         arguments: [ '@router', '@rapsys_pack.slugger_util' ]
 
 160     #Register map util class alias
 
 161     Rapsys\PackBundle\Util\MapUtil:
 
 162         alias: 'rapsys_pack.map_util'
 
 163     #Register slugger util service
 
 164     rapsys_pack.slugger_util:
 
 165         class: 'Rapsys\PackBundle\Util\SluggerUtil'
 
 166         arguments: [ '%kernel.secret%' ]
 
 168     #Register slugger util class alias
 
 169     Rapsys\PackBundle\Util\SluggerUtil:
 
 170         alias: 'rapsys_pack.slugger_util'
 
 171     #Register image controller
 
 172     Rapsys\PackBundle\Controller\ImageController:
 
 173         arguments: [ '@service_container', '@rapsys_pack.image_util', '@rapsys_pack.slugger_util', '%kernel.project_dir%/var/cache', '%rapsys_pack.path%' ]
 
 174         tags: [ 'controller.service_arguments' ]
 
 175     #Register map controller
 
 176     Rapsys\PackBundle\Controller\MapController:
 
 177         arguments: [ '@service_container', '@rapsys_pack.map_util', '@rapsys_pack.slugger_util', '%kernel.project_dir%/var/cache', '%rapsys_pack.path%' ]
 
 178         tags: [ 'controller.service_arguments' ]
 
 179     Rapsys\PackBundle\Form\CaptchaType:
 
 180         arguments: [ '@rapsys_pack.image_util', '@rapsys_pack.slugger_util', '@translator' ]
 
 181         tags: [ 'form.type' ]
 
 184 Setup configuration file `config/packages/myproject.yaml` with the following
 
 185 content available in `Resources/config/packages/rapsys_pack.yaml`:
 
 188 #Services configuration
 
 190     #Register facebook event subscriber
 
 191     Rapsys\PackBundle\Subscriber\FacebookSubscriber:
 
 192         arguments: [ '@router', [ 'en', 'en_gb', 'en_us', 'fr', 'fr_fr' ] ]
 
 193         tags: [ 'kernel.event_subscriber' ]
 
 194     #Register facebook util service
 
 195     rapsys_blog.facebook_util:
 
 196         class: 'Rapsys\PackBundle\Util\FacebookUtil'
 
 197         arguments: [ '@router',  '%kernel.project_dir%/var/cache', '%rapsys_pack.path%', 'facebook', '%kernel.project_dir%/public/png/facebook.png' ]
 
 201 Open a command console, enter your project directory and execute the following
 
 202 command to see default bundle configuration:
 
 205 $ bin/console config:dump-reference RapsysPackBundle
 
 208 Open a command console, enter your project directory and execute the following
 
 209 command to see current bundle configuration:
 
 212 $ bin/console debug:config RapsysPackBundle
 
 215 ### Step 4: Use the twig extension in your Template
 
 217 You can use a template like this to generate your first `rapsys_pack` enabled
 
 224                 <meta charset="UTF-8" />
 
 225                 <title>{% block title %}Welcome!{% endblock %}</title>
 
 226                 {% stylesheet '//fonts.googleapis.com/css?family=Irish+Grover|La+Belle+Aurore' '@NamedBundle/Resources/public/css/{reset,screen}.css' '@Short/css/example.css' %}
 
 227                         <link rel="stylesheet" type="text/css" href="{{ asset_url }}" />
 
 231                 {% block body %}{% endblock %}
 
 232                 {% javascript '@Short/js/*.js' %}
 
 233                         <script type="text/javascript" src="{{ asset_url }}"></script>
 
 239 ### Step 5: Make sure you have local binary installed
 
 241 You need to have cpack and jpack scripts from https://git.rapsys.eu/packer/ repository
 
 242 set as executable and installed in /usr/local/bin.
 
 244 To install cpack and jpack required packages open a root console and execute the
 
 248 # urpmi perl-base perl-CSS-Packer perl-JavaScript-Packer
 
 251 or stone age distributions:
 
 254 # apt-get install libcss-packer-perl libjavascript-packer-perl
 
 257 or other distributions through cpan:
 
 260 # cpan App::cpanminus
 
 262 # cpanm JavaScript::Packer
 
 265 ### Step 6: Create your own filter
 
 267 You can create you own mypackfilter class which call a mypack binary:
 
 272 namespace Rapsys\PackBundle\Filter;
 
 274 use Twig\Error\Error;
 
 276 //This class will be defined in the parameter rapsys_pack.filters.(css|img|js).[x].class string
 
 277 class MyPackFilter implements FilterInterface {
 
 278         //The constructor arguments ... will be replaced with values defined in the parameter rapsys_pack.filters.(css|img|js).[x].args array
 
 279         public function __construct(string $fileName, int $line, string $bin = 'mypack', ...) {
 
 281                 $this->fileName = $fileName;
 
 289                 //Check argument presence
 
 290                 if (!empty($this->...)) {
 
 292                         if ($this->... == '...') {
 
 293                                 $this->bin .= ' ...';
 
 295                                 //Throw an error on ...
 
 296                                 throw new Error(sprintf('Got ... for %s: %s', $this->bin, $this->...), $this->line, $this->fileName);
 
 301         //Pass merge of all inputs in content
 
 302         public function process(string $content): string {
 
 304                 $descriptorSpec = array(
 
 305                         0 => array('pipe', 'r'),
 
 306                         1 => array('pipe', 'w'),
 
 307                         2 => array('pipe', 'w')
 
 311                 if (is_resource($proc = proc_open($this->bin, $descriptorSpec, $pipes))) {
 
 312                         //Set stderr as non blocking
 
 313                         stream_set_blocking($pipes[2], false);
 
 315                         //Send content to stdin
 
 316                         fwrite($pipes[0], $content);
 
 321                         //Read content from stdout
 
 322                         if ($stdout = stream_get_contents($pipes[1])) {
 
 329                         //Read content from stderr
 
 330                         if (($stderr = stream_get_contents($pipes[2]))) {
 
 331                                 throw new Error(sprintf('Got unexpected strerr for %s: %s', $this->bin, $stderr), $this->line, $this->fileName);
 
 338                         if (($ret = proc_close($proc))) {
 
 339                                 throw new Error(sprintf('Got unexpected non zero return code %s: %d', $this->bin, $ret), $this->line, $this->fileName);
 
 349 The class must implements FilterInterface and get it's arguments through constructor.