/**
     * @group integration
     */
    public function testFilterDump()
    {
        if (!isset($_SERVER['YUI_COMPRESSOR_JAR'])) {
            $this->markTestSkipped('There is no YUI_COMPRESSOR_JAR environment variable.');
        }
        $source = <<<JAVASCRIPT
(function() {

var asdf = 'asdf';
var qwer = 'qwer';

if (asdf.indexOf(qwer)) {
    alert("That's not possible!");
} else {
    alert("Boom.");
}

})();

JAVASCRIPT;
        $expected = <<<JAVASCRIPT
(function(){var a="asdf";var b="qwer";if(a.indexOf(b)){alert("That's not possible!")}else{alert("Boom.")}})();
JAVASCRIPT;
        $asset = new StringAsset($source);
        $asset->load();
        $filter = new JsCompressorFilter($_SERVER['YUI_COMPRESSOR_JAR']);
        $filter->filterDump($asset);
        $this->assertEquals($expected, $asset->getContent(), '->filterDump()');
    }
 /**
  * Generates client-side javascript that validates form
  *
  * @param   FormView   $formView
  * @param   boolean    $overwrite
  * @throws  \RuntimeException
  */
 public function generate(FormView $formView, $overwrite = false)
 {
     // Prepare output file
     $scriptPath = $this->container->getParameter('apy_js_form_validation.script_directory');
     $scriptRealPath = $this->container->getParameter('assetic.write_to') . '/' . $scriptPath;
     $formName = isset($formView->vars['name']) ? $formView->vars['name'] : 'form';
     $scriptFile = strtolower($this->container->get('request')->get('_route')) . "_" . strtolower($formName) . ".js";
     if ($overwrite || false === file_exists($scriptRealPath . $scriptFile)) {
         // Initializes variables
         $fieldsConstraints = new FieldsConstraints();
         $gettersLibraries = new GettersLibraries($this->container, $formView);
         $aConstraints = array();
         $aGetters = array();
         $dispatcher = $this->container->get('event_dispatcher');
         // Retrieves entity name from the form view
         $entityNames = array();
         $metadata = array();
         $formViewValue = isset($formView->vars['value']) ? $formView->vars['value'] : null;
         if (is_object($formViewValue)) {
             $entityNames[] = get_class($formViewValue);
         } elseif (!empty($formView->vars['data_class']) && class_exists($formView->vars['data_class'])) {
             $entityNames[] = $formView->vars['data_class'];
         } elseif (count($formView->children) > 0) {
             foreach ($formView->children as $children) {
                 $entity = isset($children->vars['value']) ? $children->vars['value'] : null;
                 if (is_object($entity)) {
                     $entityNames[] = get_class($entity);
                 } elseif (!empty($children->vars['data_class']) && class_exists($children->vars['data_class'])) {
                     $entityNames[] = $children->vars['data_class'];
                 }
             }
         }
         if (isset($entityNames) && !empty($entityNames)) {
             foreach ($entityNames as $key => $entityName) {
                 // Form is built on Entity
                 $metadata[$key] = $this->getClassMetadata($entityName);
                 $formValidationGroups = isset($formView->vars['validation_groups']) ? $formView->vars['validation_groups'] : array('Default');
                 // Dispatch JsfvEvents::preProcess event
                 $preProcessEvent = new PreProcessEvent($formView, $metadata[$key]);
                 $dispatcher->dispatch(JsfvEvents::preProcess, $preProcessEvent);
                 if (!empty($metadata[$key]->constraints)) {
                     foreach ($metadata[$key]->constraints as $constraint) {
                         $constraintName = end(explode(chr(92), get_class($constraint)));
                         if ($constraintName == 'UniqueEntity') {
                             if (is_array($constraint->fields)) {
                                 //It has not been implemented yet
                             } else {
                                 if (is_string($constraint->fields)) {
                                     if (!isset($aConstraints[$constraint->fields])) {
                                         $aConstraints[$constraint->fields] = array();
                                     }
                                     $aConstraints[$constraint->fields][] = $constraint;
                                 }
                             }
                         }
                     }
                 }
                 $errorMapping = isset($formView->vars['error_mapping']) ? $formView->vars['error_mapping'] : null;
                 if (!empty($metadata[$key]->getters)) {
                     foreach ($metadata[$key]->getters as $getterMetadata) {
                         /* @var $getterMetadata \Symfony\Component\Validator\Mapping\GetterMetadata  */
                         if (!empty($getterMetadata->constraints)) {
                             if ($gettersLibraries->findLibrary($getterMetadata) === null) {
                                 // You have to provide getter templates in the following location
                                 // {EntityBundle}/Resources/views/Getters/{EntityName}.{GetterMethod}.js.twig
                                 // or all templates in one place:
                                 // app/Resources/APYJsFormValidationBundle/views/Getters/{EntityName}.{GetterMethod}.js.twig
                                 continue;
                             }
                             foreach ($getterMetadata->constraints as $constraint) {
                                 /* @var $constraint \Symfony\Component\Validator */
                                 $getterName = $getterMetadata->getName();
                                 $jsHandlerCallback = $gettersLibraries->getKey($getterMetadata, '_');
                                 $constraintName = end(explode(chr(92), get_class($constraint)));
                                 $constraintProperties = get_object_vars($constraint);
                                 $exist = array_intersect($formValidationGroups, $constraintProperties['groups']);
                                 if (!empty($exist)) {
                                     if (!$gettersLibraries->has($getterMetadata)) {
                                         $gettersLibraries->add($getterMetadata);
                                     }
                                     if (!$fieldsConstraints->hasLibrary($constraintName)) {
                                         $librairy = "APYJsFormValidationBundle:Constraints:{$constraintName}Validator.js.twig";
                                         $fieldsConstraints->addLibrary($constraintName, $librairy);
                                     }
                                     if (!empty($errorMapping[$getterName]) && is_string($errorMapping[$getterName])) {
                                         $fieldName = $errorMapping[$getterName];
                                         //'type' property is set in RepeatedTypeExtension class
                                         if (!empty($formView->children[$fieldName]) && isset($formView->children[$fieldName]->vars['type']) && $formView->children[$fieldName]->vars['type'] == 'repeated') {
                                             $repeatedNames = array_keys($formView->children[$fieldName]->vars['value']);
                                             //Listen first repeated element
                                             $fieldId = $formView->children[$fieldName]->vars['id'] . "_" . $repeatedNames[0];
                                         } else {
                                             $fieldId = $formView->children[$fieldName]->vars['id'];
                                         }
                                     } else {
                                         $fieldId = '.';
                                     }
                                     if (!isset($aGetters[$fieldId][$jsHandlerCallback])) {
                                         $aGetters[$fieldId][$jsHandlerCallback] = array();
                                     }
                                     unset($constraintProperties['groups']);
                                     $aGetters[$fieldId][$jsHandlerCallback][] = array('name' => $constraintName, 'parameters' => json_encode($constraintProperties));
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (isset($entityNames) && !empty($entityNames)) {
             $constraintsTarget = array();
             foreach ($entityNames as $key => $entity) {
                 $constraintsTarget = array_merge($constraintsTarget, $metadata[$key]->properties);
             }
         } else {
             // Simple form that is built manually
             $constraintsTarget = isset($formView->vars['constraints']) ? $formView->vars['constraints'] : null;
             if (isset($constraintsTarget[0]) && !empty($constraintsTarget[0]->fields)) {
                 //Get Default group ?
                 $constraintsTarget = $constraintsTarget[0]->fields;
             }
         }
         if (!empty($constraintsTarget)) {
             // we look through each field of the form
             foreach ($formView->children as $formField) {
                 $names = array();
                 $names[] = $formField;
                 if (!empty($formField->children)) {
                     foreach ($formField->children as $nextLevelChildren) {
                         $names[] = $nextLevelChildren;
                     }
                 }
                 foreach ($names as $formFieldN) {
                     /* @var $formField \Symfony\Component\Form\FormView */
                     // Fields with property_path=false must be excluded from validation
                     if (isset($formFieldN->vars['property_path']) && $formFieldN->vars['property_path'] === false) {
                         continue;
                     }
                     //Setting "property_path" to "false" is deprecated since version 2.1 and will be removed in 2.3.
                     //Set "mapped" to "false" instead
                     if (isset($formFieldN->vars['mapped']) && $formFieldN->vars['mapped'] === false) {
                         continue;
                     }
                     // we look for constraints for the field
                     if (!isset($constraintsTarget[$formFieldN->vars['name']])) {
                         continue;
                     }
                     $constraintList = isset($entityName) ? $constraintsTarget[$formFieldN->vars['name']]->getConstraints() : $constraintsTarget[$formFieldN->vars['name']]->constraints;
                     //Adds entity level constraints that have been provided for this field
                     if (!empty($aConstraints[$formFieldN->vars['name']])) {
                         $constraintList = array_merge($constraintList, $aConstraints[$formFieldN->vars['name']]);
                     }
                     // we look through each field constraint
                     foreach ($constraintList as $constraint) {
                         $constraintName = end(explode(chr(92), get_class($constraint)));
                         $constraintProperties = get_object_vars($constraint);
                         // Groups are no longer needed
                         unset($constraintProperties['groups']);
                         if (!$fieldsConstraints->hasLibrary($constraintName)) {
                             $librairy = "APYJsFormValidationBundle:Constraints:{$constraintName}Validator.js.twig";
                             $fieldsConstraints->addLibrary($constraintName, $librairy);
                         }
                         $constraintParameters = array();
                         //We need to know entity class for the field which is applied by UniqueEntity constraint
                         if ($constraintName == 'UniqueEntity' && !empty($formFieldN->parent)) {
                             $entity = isset($formFieldN->parent->vars['value']) ? $formFieldN->parent->vars['value'] : null;
                             if (isset($formView->children[$this->getParameter('identifier_field')])) {
                                 $id = json_encode($formView->children[$this->getParameter('identifier_field')]->vars['id']);
                             } else {
                                 $id = json_encode($formFieldN->vars['id']);
                             }
                             $constraintParameters += array('entity:' . json_encode(get_class($entity)), 'identifier_field_id:' . $id);
                         }
                         foreach ($constraintProperties as $variable => $value) {
                             if (is_array($value)) {
                                 $value = json_encode($value);
                             } else {
                                 // regex
                                 if (stristr('pattern', $variable) === false) {
                                     $value = json_encode($value);
                                 }
                             }
                             $constraintParameters[] = "{$variable}:{$value}";
                         }
                         $fieldsConstraints->addFieldConstraint($formFieldN->vars['id'], array('name' => $constraintName, 'parameters' => '{' . join(', ', $constraintParameters) . '}'));
                     }
                 }
             }
         }
         // Dispatch JsfvEvents::postProcess event
         $postProcessEvent = new PostProcessEvent($formView, $fieldsConstraints);
         $dispatcher->dispatch(JsfvEvents::postProcess, $postProcessEvent);
         // Retrieve validation mode from configuration
         $check_modes = array('submit' => false, 'blur' => false, 'change' => false);
         foreach ($this->container->getParameter('apy_js_form_validation.check_modes') as $check_mode) {
             $check_modes[$check_mode] = true;
         }
         // Render the validation script
         $validation_bundle = $this->getValidationBundle();
         $javascript_framework = strtolower($this->container->getParameter('apy_js_form_validation.javascript_framework'));
         $dataTemplate = array('formName' => $formName, 'fieldConstraints' => $fieldsConstraints->getFieldsConstraints(), 'librairyCalls' => $fieldsConstraints->getLibraries(), 'check_modes' => $check_modes, 'getterHandlers' => $gettersLibraries->all(), 'gettersConstraints' => $aGetters, 'translation_group' => $this->container->getParameter('apy_js_form_validation.translation_group'));
         $template = $this->container->get('templating')->render("{$validation_bundle}:Frameworks:JsFormValidation.js.{$javascript_framework}.twig", $dataTemplate);
         // Create asset and compress it
         $asset = new AssetCollection();
         $asset->setContent($template);
         $asset->setTargetPath($scriptRealPath . $scriptFile);
         // Js compression
         if ($this->container->getParameter('apy_js_form_validation.yui_js')) {
             $yui = new JsCompressorFilter($this->container->getParameter('assetic.filter.yui_js.jar'), $this->container->getParameter('assetic.java.bin'));
             $yui->filterDump($asset);
         }
         $this->container->get('filesystem')->mkdir($scriptRealPath);
         if (false === @file_put_contents($asset->getTargetPath(), $asset->getContent())) {
             throw new \RuntimeException('Unable to write file ' . $asset->getTargetPath());
         }
     }
     return $this->container->get('templating.helper.assets')->getUrl($scriptPath . $scriptFile);
 }
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     try {
         // Potion config
         if ($this->config === false) {
             throw new \Exception('Invalid potion configuration, please run "artisan vendor:publish" in your project root to public the potion config file.');
         }
         // Clean up paths
         $this->config['resource_path'] = rtrim($this->config['resource_path'], '/');
         $this->config['resource_path'] = rtrim($this->config['resource_path'], '\\');
         $this->config['assets_path'] = rtrim($this->config['assets_path'], '/');
         $this->config['assets_path'] = rtrim($this->config['assets_path'], '\\');
         // Make the assets path
         if (!$this->makePath($this->config['assets_path'])) {
             throw new \Exception("Unable to make assets_path from config: {$this->config['assets_path']}");
         }
         // Filters
         $filters = [];
         // -- optipng
         $filter = new OptiPngFilter($this->config['filters']['optipng']['path']);
         $filter->setLevel($this->config['filters']['optipng']['level']);
         $filters['optipng'] = $filter;
         // -- jpegoptim
         $filter = new JpegoptimFilter($this->config['filters']['jpegoptim']['path']);
         $filter->setStripAll($this->config['filters']['jpegoptim']['strip']);
         $filter->setMax($this->config['filters']['jpegoptim']['max']);
         $filters['jpegoptim'] = $filter;
         // -- Css import
         $filter = new CssImportFilter();
         $filters['css_import'] = $filter;
         // -- Css rewrite
         $filter = new CssRewriteFilter();
         $filters['css_rewrite'] = $filter;
         // -- Css min
         $filter = new CssMinFilter();
         $filters['css_min'] = $filter;
         // -- Css Yui
         $filter = new CssCompressorFilter($this->config['filters']['css_yui']['path_jar'], $this->config['filters']['css_yui']['path_java']);
         $filters['css_yui'] = $filter;
         // -- CSS LessPHP
         $filter = new LessphpFilter();
         $filter->setLoadPaths($this->config['filters']['css_lessphp']['path_imports']);
         $filter->setFormatter($this->config['filters']['css_lessphp']['format']);
         $filter->setPreserveComments($this->config['filters']['css_lessphp']['preserve_comments']);
         $filters['css_lessphp'] = $filter;
         // -- CSS ScssPHP
         $filter = new ScssphpFilter();
         $filter->setImportPaths($this->config['filters']['css_scssphp']['path_imports']);
         $filter->setFormatter($this->config['filters']['css_scssphp']['format']);
         $filters['css_scssphp'] = $filter;
         // -- JS Min
         $filter = new JSMinFilter();
         $filters['js_min'] = $filter;
         // -- Js Yui
         $filter = new JsCompressorFilter($this->config['filters']['js_yui']['path_jar'], $this->config['filters']['js_yui']['path_java']);
         $filter->setNomunge($this->config['filters']['js_yui']['no_munge']);
         $filter->setPreserveSemi($this->config['filters']['js_yui']['preserve_semi']);
         $filter->setDisableOptimizations($this->config['filters']['js_yui']['disable_opti']);
         $filters['js_yui'] = $filter;
         // Cache
         $cache = [];
         // Each potion
         foreach ($this->config['potions'] as $potion) {
             // -- Find assets
             $resource_filters = [];
             foreach ($potion['filters'] as $filter) {
                 $resource_filters[] = $filters[$filter];
             }
             // -- Asset content
             $asset_content = '';
             // -- Resources
             foreach ($potion['resources'] as $resource) {
                 // -- -- Make full path
                 $resource = ltrim($resource, '/');
                 $resource = ltrim($resource, '\\');
                 $asset_path = $this->config['resource_path'] . DIRECTORY_SEPARATOR . $resource;
                 // -- -- Echo
                 $this->info("Processing resource: {$asset_path}");
                 // -- -- Get path info
                 $pathinfo = pathinfo($asset_path);
                 // -- -- File assets
                 $file_assets = [];
                 // -- -- Glob?
                 if ($pathinfo['extension'] == '*' || $pathinfo['filename'] == '*') {
                     // -- -- -- Get all file assets
                     $glob = new GlobAsset($asset_path, $resource_filters);
                     foreach ($glob->all() as $file_asset) {
                         $file_assets[] = new FileAsset(rtrim($file_asset->getSourceRoot(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file_asset->getSourcePath(), $resource_filters);
                     }
                 } else {
                     $file_assets[] = new FileAsset($asset_path, $resource_filters);
                 }
                 // -- -- Each file asset
                 foreach ($file_assets as $file_asset) {
                     // -- -- -- File
                     $file_path = $this->config['assets_path'] . DIRECTORY_SEPARATOR . $file_asset->getSourcePath();
                     // -- -- -- Echo
                     $this->info("Processing resource file: {$file_path}");
                     // -- -- -- Make file, or combine
                     if ($potion['output'] !== false) {
                         $asset_content .= $file_asset->dump();
                     } else {
                         // -- -- -- -- Echo
                         $this->info("Writing asset file: {$file_path}");
                         // -- -- -- -- Write
                         if (file_put_contents($file_path, $file_asset->dump()) === false) {
                             $this->error("Error writing asset file: {$file_path}");
                         }
                         // -- -- -- -- Add to cache
                         $cache[$file_asset->getSourcePath()] = $this->versionFile($file_path);
                     }
                 }
             }
             // -- Combine to a single file
             if ($potion['output'] !== false) {
                 // -- -- Write to file
                 $file_path = $this->config['assets_path'] . DIRECTORY_SEPARATOR . $potion['output'];
                 // -- -- Echo
                 $this->info("Writing asset file: {$file_path}");
                 // -- -- Write
                 if (file_put_contents($file_path, $asset_content) === false) {
                     $this->error("Error writing asset file: {$file_path}");
                 }
                 // -- -- Add to cache
                 $cache[$potion['output']] = $this->versionFile($file_path);
             }
         }
         // Set cache
         Cache::forever('potion_assets', $cache);
     } catch (\Exception $e) {
         // Echo
         $this->error($e->getMessage());
     }
 }