Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save carlosromero/56e9d00d54b578db3511 to your computer and use it in GitHub Desktop.
Save carlosromero/56e9d00d54b578db3511 to your computer and use it in GitHub Desktop.
<?php
namespace My\Bundle\Command;
use Assetic\Asset\AssetInterface;
use Assetic\Util\VarUtils;
use Symfony\Bundle\AsseticBundle\Command\DumpCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Finder\Finder;
class AsseticAmazonCommand extends DumpCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->s3client = $this->getContainer()->get('fdi.cliperest.storage.amazon_s3');
$this->s3client->registerStreamWrapper();
$this->bucketName = $this->getContainer()->getParameter('amazon_s3.bucket_name');
$this->directoryAssetic = $this->getContainer()->getParameter('amazon_s3.directory_assetic');
$output->writeln('Checking Amazon S3 assets mime types');
return parent::execute($input, $output);
}
/**
* Copied because we need to overwrite private method doDump from parent class
*
* Writes an asset.
*
* If the application or asset is in debug mode, each leaf asset will be
* dumped as well.
*
* @param string $name An asset name
* @param OutputInterface $stdout The command output
*/
public function dumpAsset($name, OutputInterface $stdout)
{
$asset = $this->am->get($name);
$formula = $this->am->getFormula($name);
// start by dumping the main asset
$this->doDump($asset, $stdout);
$debug = isset($formula[2]['debug']) ? $formula[2]['debug'] : $this->am->isDebug();
$combine = isset($formula[2]['combine']) ? $formula[2]['combine'] : !$debug;
// dump each leaf if no combine
if (!$combine) {
foreach ($asset as $leaf) {
$this->doDump($leaf, $stdout);
}
}
}
/**
* Copied from parent class, we need to add some lines here in order to add metadata info in amazon S3 files
*
* Performs the asset dump.
*
* @param AssetInterface $asset An asset
* @param OutputInterface $stdout The command output
*
* @throws RuntimeException If there is a problem writing the asset
*/
private function doDump(AssetInterface $asset, OutputInterface $stdout)
{
$combinations = VarUtils::getCombinations(
$asset->getVars(),
$this->getContainer()->getParameter('assetic.variables')
);
foreach ($combinations as $combination) {
$asset->setValues($combination);
// resolve the target path
$target = rtrim($this->basePath, '/').'/'.$asset->getTargetPath();
$target = str_replace('_controller/', '', $target);
$target = VarUtils::resolve($target, $asset->getVars(), $asset->getValues());
if (!is_dir($dir = dirname($target))) {
$stdout->writeln(sprintf(
'<comment>%s</comment> <info>[dir+]</info> %s',
date('H:i:s'),
$dir
));
if (false === @mkdir($dir, 0777, true)) {
throw new \RuntimeException('Unable to create directory '.$dir);
}
}
$stdout->writeln(sprintf(
'<comment>%s</comment> <info>[file+]</info> %s',
date('H:i:s'),
$target
));
if (OutputInterface::VERBOSITY_VERBOSE <= $stdout->getVerbosity()) {
if ($asset instanceof AssetCollectionInterface) {
foreach ($asset as $leaf) {
$root = $leaf->getSourceRoot();
$path = $leaf->getSourcePath();
$stdout->writeln(sprintf(' <comment>%s/%s</comment>', $root ?: '[unknown root]', $path ?: '[unknown path]'));
}
} else {
$root = $asset->getSourceRoot();
$path = $asset->getSourcePath();
$stdout->writeln(sprintf(' <comment>%s/%s</comment>', $root ?: '[unknown root]', $path ?: '[unknown path]'));
}
}
// I prefer this way, but stream_context does nothing
//if (false === file_put_contents($target, $asset->dump(), null, stream_context_create(array('s3' => array('content_type' => $mimeType))))) {
if (false === @file_put_contents($target, $asset->dump())) {
throw new \RuntimeException('Unable to write file '.$target);
}
//new lines for Amazon mime types
if (substr($target, 0, 3) === 's3:') {
$extension = explode('.', $asset->getTargetPath());
$extension = array_pop($extension);
$mimeType = \CFMimeTypes::get_mimetype($extension);
$key = $this->directoryAssetic . $asset->getTargetPath();
$this->s3client->change_content_type($this->bucketName, $key , $mimeType);
$stdout->writeln("Amazons3 - content_type: $mimeType");
}
}
}
}
@jandom
Copy link

jandom commented Feb 19, 2016

This is exceptionally useful, actually!

Dumping assets with php app/console assetic:dump consistently dropped mimeTypes on CSS files to application/octet-stream necessitating changes on the S3 to text/css to things working again.

I took a different but related approach. Copied over DumpCommand.php and AbstractCommand.php from assetic bundle into MyBundle/Command, then appended to the end:


            if (false === @file_put_contents($target, $asset->dump())) {
                throw new \RuntimeException('Unable to write file '.$target);
            }

            //new lines for Amazon mime types
            $s3client = $this->getContainer()->get('my_bundle.amazon_s3');
            // not needed if registered inside boot() in app/AppKernel.php
            //$s3client->registerStreamWrapper();
            $bucketName = $this->getContainer()->getParameter('amazon_s3_bucket_name');

            if (substr($target, 0, 3) === 's3:') {
                $extension = explode('.', $asset->getTargetPath());
                $extension = array_pop($extension);
                $mimeType = \CFMimeTypes::get_mimetype($extension);
                $key = $asset->getTargetPath();
                $s3client->change_content_type($bucketName, $key , $mimeType);
                $stdout->writeln("Amazons3 -  content_type:  $bucketName, $key, $mimeType");
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment