Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php /* * This file is a part of Sculpin. * * (c) Dragonfly Development Inc. * * Fo..
Decoded Output download
<?php
/*
* This file is a part of Sculpin.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sculpin\Bundle\ContentTypesBundle\Command;
use Sculpin\Bundle\SculpinBundle\Command\AbstractCommand;
use Sculpin\Bundle\SculpinBundle\Console\Application;
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\Filesystem\Filesystem;
use Symfony\Component\String\Inflector\EnglishInflector;
/**
* Helper command to create a new content type.
*
* Outputs the YAML required to add a new content type, and optionally
* generates the associated boilerplate for the type.
*/
final class ContentCreateCommand extends AbstractCommand
{
private const DIRECTORY_FLAG = '_directory_';
/**
* {@inheritdoc}
*/
protected function configure(): void
{
$prefix = $this->isStandaloneSculpin() ? '' : 'sculpin:';
$this->setName($prefix . 'content:create');
$this->setDescription('Create a new content type, including boilerplate template files.');
$this->setDefinition(
[
new InputArgument(
'type',
InputArgument::REQUIRED,
'Name for this type (e.g., "posts")'
),
new InputOption(
'boilerplate',
'b',
InputOption::VALUE_NONE,
'Enabled by default. Use --dry-run if you do not want to generate the files.'
),
new InputOption(
'dry-run',
'd',
InputOption::VALUE_NONE,
'Don\'t generate boilerplate/placeholder/template files.'
),
new InputOption(
'taxonomy',
't',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
"Organize content by taxonomy categories (\"tags\", \"categories\", \"types\", etc)
"
. "Add multiple taxonomies by repeating the option."
)
]
);
$this->setHelp(<<<EOT
The <info>content:create</info> command helps you create a custom content type and the associated boilerplate/templates.
Example:
vendor/bin/sculpin content:create docs -t product -t year
NOTE: This command does not automatically modify the <info>app/config/sculpin_kernel.yml</info> file. You will have to
add the suggested changes yourself.
EOT
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$pluralType = $input->getArgument('type');
$singularType = (new EnglishInflector())->singularize($pluralType)[0];
$dryRun = $input->getOption('dry-run');
$taxonomies = $input->getOption('taxonomy');
$output->writeln('Generating new content type: <info>' . $pluralType . '</info>');
// TODO: Prompt the user with a preview before generating content
$output->writeln($this->getOutputMessage($pluralType, $singularType, $taxonomies));
// TODO: Write a yaml file to configure the content type (and recommend a wildcard include for types?)
// grab the boilerplate manifest
$boilerplateManifest = $this->generateBoilerplateManifest($pluralType, $singularType, $taxonomies);
// skip creating boilerplate files if this is a dry run
if ($dryRun) {
$output->writeln("Dry run. Skipping creation of these boilerplate files:");
foreach ($boilerplateManifest as $filename => $value) {
$output->writeln(" <info>" . $filename . '</info>');
}
$output->writeln("
Remember to add the content type definition (displayed above) to sculpin_kernel.yml!");
return 0;
}
$output->writeln('Generating boilerplate for ' . $pluralType);
$fs = new Filesystem();
foreach ($boilerplateManifest as $filename => $value) {
// create directory and skip the rest of the loop
if ($value === static::DIRECTORY_FLAG) {
$fs->mkdir($filename);
continue;
}
if ($fs->exists($filename)) {
$output->writeln('Warning: ' . $filename . ' already exists at the target location. Skipping.');
continue;
}
// create file $filename with contents $value
$fs->dumpFile($filename, $value);
}
$output->writeln("
Remember to add the content type definition (displayed above) to sculpin_kernel.yml!");
return 0;
}
private function generateBoilerplateManifest(string $plural, string $singular, array $taxonomies = []): array
{
$app = $this->getApplication();
if (!$app instanceof Application) {
throw new \RuntimeException('Sculpin Application not found!');
}
$rootDir = \dirname($app->getKernel()->getProjectDir());
$manifest = [];
// ensure the content type storage folder exists
$storageFolder = $rootDir . '/source/_' . $plural;
$manifest[$storageFolder] = static::DIRECTORY_FLAG;
// content type index template
$index = $rootDir . '/source/' . $plural . '.html';
$manifest[$index] = $this->getIndexTemplate($plural, $singular);
// ensure the views folder exists
$storageFolder = $rootDir . '/source/_views';
$manifest[$storageFolder] = static::DIRECTORY_FLAG;
// content type view template
$index = $rootDir . '/source/_views/' . $singular . '.html';
$manifest[$index] = $this->getViewTemplate($plural, $taxonomies);
foreach ($taxonomies as $taxonomy) {
$singularTaxonomy = (new EnglishInflector())->singularize($taxonomy)[0];
// content taxonomy index template
$index = $rootDir . '/source/' . $plural . '/' . $taxonomy . '.html';
$manifest[$index] = $this->getTaxonomyIndexTemplate($plural, $taxonomy, $singularTaxonomy);
// content taxonomy directory
$storageFolder = $rootDir . '/source/' . $plural . '/' . $taxonomy;
$manifest[$storageFolder] = static::DIRECTORY_FLAG;
// content taxonomy view template(s)
$index = $rootDir . '/source/' . $plural . '/' . $taxonomy . '/' . $singularTaxonomy . '.html';
$manifest[$index] = $this->getTaxonomyViewTemplate($plural, $singular, $singularTaxonomy);
}
return $manifest;
}
private function getOutputMessage(string $type, string $singularType, array $taxonomies = []): string
{
$outputMessage = <<<EOT
YAML content type definition you will have to
add to <info>app/config/sculpin_kernel.yml</info>:
================START OF YAML================
sculpin_content_types:
{$type}:
type: path
path: _{$type}
singular_name: {$singularType}
layout: {$singularType}
enabled: true
permalink: {$type}/:title
EOT;
if ($taxonomies) {
$outputMessage .= "
taxonomies:
";
foreach ($taxonomies as $taxonomy) {
$outputMessage .= " - {$taxonomy}
";
}
}
$outputMessage .= "
=================END OF YAML=================
";
return $outputMessage;
}
private function getIndexTemplate(string $plural, string $singular)
{
$title = ucfirst($plural);
return <<<EOT
---
layout: default
title: $title
generator: pagination
pagination:
provider: data.$plural
max_per_page: 10
use: [$plural]
---
<ul>
{% for $singular in page.pagination.items %}
<li><a href="{{ $singular.url }}">{{ $singular.title }}</a></li>
{% endfor %}
</ul>
<nav>
{% if page.pagination.previous_page or page.pagination.next_page %}
{% if page.pagination.previous_page %}
<a href="{{ site.url }}{{ page.pagination.previous_page.url }}">Newer {$title}</a>
{% endif %}
{% if page.pagination.next_page %}
<a href="{{ site.url }}{{ page.pagination.next_page.url }}">Older {$title}</a>
{% endif %}
{% endif %}
</nav>
EOT;
}
private function getViewTemplate(string $plural, array $taxonomies = []): string
{
$output = <<<EOT
{% extends 'default' %}
{% block content_wrapper %}
<article>
<header>
<h2>{{ page.title }}</h2>
{% if page.subtitle %}
<h3 class="subtitle">{{ page.subtitle }}</h3>
{% endif %}
</header>
<section class="main_body">
{{ page.blocks.content|raw }}
</section>
EOT;
if ($taxonomies) {
$output .= "
" . ' <section class="taxonomies">' . "
";
foreach ($taxonomies as $taxonomy) {
$capitalTaxonomy = ucwords($taxonomy);
$singularTaxonomy = (new EnglishInflector())->singularize($taxonomy)[0];
$output .= <<<EOT
<div class="taxonomy">
<a href="{{site.url }}/{$plural}/{$taxonomy}">{$capitalTaxonomy}</a>:
{% for {$singularTaxonomy} in page.{$taxonomy} %}
<a href="{{ site.url }}/{$plural}/{$taxonomy}/{{ {$singularTaxonomy} }}">
{{ {$singularTaxonomy} }}
</a>{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
EOT;
}
$output .= "
" . ' </section>' . "
";
}
$output .= <<<EOT
<footer>
<p class="published_date">Published: {{page.date|date('F j, Y')}}</p>
</footer>
</article>
{% endblock content_wrapper %}
EOT;
return $output;
}
private function getTaxonomyIndexTemplate(
string $plural,
string $taxonomy,
string $singularTaxonomy
): string {
$title = ucfirst($taxonomy);
return <<<EOT
---
layout: default
use: [{$plural}_{$taxonomy}]
---
<h1>{$title}</h1>
<ul>
{% for {$singularTaxonomy},{$plural} in data.{$plural}_{$taxonomy} %}
<li>
<a href="/{$plural}/{$taxonomy}/{{ {$singularTaxonomy}|url_encode(true) }}">{{ {$singularTaxonomy} }}</a>
</li>
{% endfor %}
</ul>
EOT;
}
private function getTaxonomyViewTemplate(
string $plural,
string $singular,
string $singularTaxonomy
): string {
$title = ucfirst($plural);
return <<<EOT
---
layout: default
generator: [{$plural}_{$singularTaxonomy}_index, pagination]
pagination:
provider: page.{$singularTaxonomy}_{$plural}
max_per_page: 10
---
<h1>{{ page.{$singularTaxonomy}|capitalize }}</h1>
<ul>
{% for {$singular} in page.pagination.items %}
<li><a href="{{ {$singular}.url }}">{{ {$singular}.title }}</a></li>
{% endfor %}
</ul>
<nav>
{% if page.pagination.previous_page or page.pagination.next_page %}
{% if page.pagination.previous_page %}
<a href="{{ site.url }}{{ page.pagination.previous_page.url }}">Newer {$title}</a>
{% endif %}
{% if page.pagination.next_page %}
<a href="{{ site.url }}{{ page.pagination.next_page.url }}">Older {$title}</a>
{% endif %}
{% endif %}
</nav>
EOT;
}
}
?>
Did this file decode correctly?
Original Code
<?php
/*
* This file is a part of Sculpin.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sculpin\Bundle\ContentTypesBundle\Command;
use Sculpin\Bundle\SculpinBundle\Command\AbstractCommand;
use Sculpin\Bundle\SculpinBundle\Console\Application;
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\Filesystem\Filesystem;
use Symfony\Component\String\Inflector\EnglishInflector;
/**
* Helper command to create a new content type.
*
* Outputs the YAML required to add a new content type, and optionally
* generates the associated boilerplate for the type.
*/
final class ContentCreateCommand extends AbstractCommand
{
private const DIRECTORY_FLAG = '_directory_';
/**
* {@inheritdoc}
*/
protected function configure(): void
{
$prefix = $this->isStandaloneSculpin() ? '' : 'sculpin:';
$this->setName($prefix . 'content:create');
$this->setDescription('Create a new content type, including boilerplate template files.');
$this->setDefinition(
[
new InputArgument(
'type',
InputArgument::REQUIRED,
'Name for this type (e.g., "posts")'
),
new InputOption(
'boilerplate',
'b',
InputOption::VALUE_NONE,
'Enabled by default. Use --dry-run if you do not want to generate the files.'
),
new InputOption(
'dry-run',
'd',
InputOption::VALUE_NONE,
'Don\'t generate boilerplate/placeholder/template files.'
),
new InputOption(
'taxonomy',
't',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
"Organize content by taxonomy categories (\"tags\", \"categories\", \"types\", etc)\n"
. "Add multiple taxonomies by repeating the option."
)
]
);
$this->setHelp(<<<EOT
The <info>content:create</info> command helps you create a custom content type and the associated boilerplate/templates.
Example:
vendor/bin/sculpin content:create docs -t product -t year
NOTE: This command does not automatically modify the <info>app/config/sculpin_kernel.yml</info> file. You will have to
add the suggested changes yourself.
EOT
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$pluralType = $input->getArgument('type');
$singularType = (new EnglishInflector())->singularize($pluralType)[0];
$dryRun = $input->getOption('dry-run');
$taxonomies = $input->getOption('taxonomy');
$output->writeln('Generating new content type: <info>' . $pluralType . '</info>');
// TODO: Prompt the user with a preview before generating content
$output->writeln($this->getOutputMessage($pluralType, $singularType, $taxonomies));
// TODO: Write a yaml file to configure the content type (and recommend a wildcard include for types?)
// grab the boilerplate manifest
$boilerplateManifest = $this->generateBoilerplateManifest($pluralType, $singularType, $taxonomies);
// skip creating boilerplate files if this is a dry run
if ($dryRun) {
$output->writeln("Dry run. Skipping creation of these boilerplate files:");
foreach ($boilerplateManifest as $filename => $value) {
$output->writeln("\t<info>" . $filename . '</info>');
}
$output->writeln("\nRemember to add the content type definition (displayed above) to sculpin_kernel.yml!");
return 0;
}
$output->writeln('Generating boilerplate for ' . $pluralType);
$fs = new Filesystem();
foreach ($boilerplateManifest as $filename => $value) {
// create directory and skip the rest of the loop
if ($value === static::DIRECTORY_FLAG) {
$fs->mkdir($filename);
continue;
}
if ($fs->exists($filename)) {
$output->writeln('Warning: ' . $filename . ' already exists at the target location. Skipping.');
continue;
}
// create file $filename with contents $value
$fs->dumpFile($filename, $value);
}
$output->writeln("\nRemember to add the content type definition (displayed above) to sculpin_kernel.yml!");
return 0;
}
private function generateBoilerplateManifest(string $plural, string $singular, array $taxonomies = []): array
{
$app = $this->getApplication();
if (!$app instanceof Application) {
throw new \RuntimeException('Sculpin Application not found!');
}
$rootDir = \dirname($app->getKernel()->getProjectDir());
$manifest = [];
// ensure the content type storage folder exists
$storageFolder = $rootDir . '/source/_' . $plural;
$manifest[$storageFolder] = static::DIRECTORY_FLAG;
// content type index template
$index = $rootDir . '/source/' . $plural . '.html';
$manifest[$index] = $this->getIndexTemplate($plural, $singular);
// ensure the views folder exists
$storageFolder = $rootDir . '/source/_views';
$manifest[$storageFolder] = static::DIRECTORY_FLAG;
// content type view template
$index = $rootDir . '/source/_views/' . $singular . '.html';
$manifest[$index] = $this->getViewTemplate($plural, $taxonomies);
foreach ($taxonomies as $taxonomy) {
$singularTaxonomy = (new EnglishInflector())->singularize($taxonomy)[0];
// content taxonomy index template
$index = $rootDir . '/source/' . $plural . '/' . $taxonomy . '.html';
$manifest[$index] = $this->getTaxonomyIndexTemplate($plural, $taxonomy, $singularTaxonomy);
// content taxonomy directory
$storageFolder = $rootDir . '/source/' . $plural . '/' . $taxonomy;
$manifest[$storageFolder] = static::DIRECTORY_FLAG;
// content taxonomy view template(s)
$index = $rootDir . '/source/' . $plural . '/' . $taxonomy . '/' . $singularTaxonomy . '.html';
$manifest[$index] = $this->getTaxonomyViewTemplate($plural, $singular, $singularTaxonomy);
}
return $manifest;
}
private function getOutputMessage(string $type, string $singularType, array $taxonomies = []): string
{
$outputMessage = <<<EOT
YAML content type definition you will have to
add to <info>app/config/sculpin_kernel.yml</info>:
================START OF YAML================
sculpin_content_types:
{$type}:
type: path
path: _{$type}
singular_name: {$singularType}
layout: {$singularType}
enabled: true
permalink: {$type}/:title
EOT;
if ($taxonomies) {
$outputMessage .= "\n taxonomies:\n";
foreach ($taxonomies as $taxonomy) {
$outputMessage .= " - {$taxonomy}\n";
}
}
$outputMessage .= "\n=================END OF YAML=================\n\n";
return $outputMessage;
}
private function getIndexTemplate(string $plural, string $singular)
{
$title = ucfirst($plural);
return <<<EOT
---
layout: default
title: $title
generator: pagination
pagination:
provider: data.$plural
max_per_page: 10
use: [$plural]
---
<ul>
{% for $singular in page.pagination.items %}
<li><a href="{{ $singular.url }}">{{ $singular.title }}</a></li>
{% endfor %}
</ul>
<nav>
{% if page.pagination.previous_page or page.pagination.next_page %}
{% if page.pagination.previous_page %}
<a href="{{ site.url }}{{ page.pagination.previous_page.url }}">Newer {$title}</a>
{% endif %}
{% if page.pagination.next_page %}
<a href="{{ site.url }}{{ page.pagination.next_page.url }}">Older {$title}</a>
{% endif %}
{% endif %}
</nav>
EOT;
}
private function getViewTemplate(string $plural, array $taxonomies = []): string
{
$output = <<<EOT
{% extends 'default' %}
{% block content_wrapper %}
<article>
<header>
<h2>{{ page.title }}</h2>
{% if page.subtitle %}
<h3 class="subtitle">{{ page.subtitle }}</h3>
{% endif %}
</header>
<section class="main_body">
{{ page.blocks.content|raw }}
</section>
EOT;
if ($taxonomies) {
$output .= "\n" . ' <section class="taxonomies">' . "\n";
foreach ($taxonomies as $taxonomy) {
$capitalTaxonomy = ucwords($taxonomy);
$singularTaxonomy = (new EnglishInflector())->singularize($taxonomy)[0];
$output .= <<<EOT
<div class="taxonomy">
<a href="{{site.url }}/{$plural}/{$taxonomy}">{$capitalTaxonomy}</a>:
{% for {$singularTaxonomy} in page.{$taxonomy} %}
<a href="{{ site.url }}/{$plural}/{$taxonomy}/{{ {$singularTaxonomy} }}">
{{ {$singularTaxonomy} }}
</a>{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
EOT;
}
$output .= "\n" . ' </section>' . "\n";
}
$output .= <<<EOT
<footer>
<p class="published_date">Published: {{page.date|date('F j, Y')}}</p>
</footer>
</article>
{% endblock content_wrapper %}
EOT;
return $output;
}
private function getTaxonomyIndexTemplate(
string $plural,
string $taxonomy,
string $singularTaxonomy
): string {
$title = ucfirst($taxonomy);
return <<<EOT
---
layout: default
use: [{$plural}_{$taxonomy}]
---
<h1>{$title}</h1>
<ul>
{% for {$singularTaxonomy},{$plural} in data.{$plural}_{$taxonomy} %}
<li>
<a href="/{$plural}/{$taxonomy}/{{ {$singularTaxonomy}|url_encode(true) }}">{{ {$singularTaxonomy} }}</a>
</li>
{% endfor %}
</ul>
EOT;
}
private function getTaxonomyViewTemplate(
string $plural,
string $singular,
string $singularTaxonomy
): string {
$title = ucfirst($plural);
return <<<EOT
---
layout: default
generator: [{$plural}_{$singularTaxonomy}_index, pagination]
pagination:
provider: page.{$singularTaxonomy}_{$plural}
max_per_page: 10
---
<h1>{{ page.{$singularTaxonomy}|capitalize }}</h1>
<ul>
{% for {$singular} in page.pagination.items %}
<li><a href="{{ {$singular}.url }}">{{ {$singular}.title }}</a></li>
{% endfor %}
</ul>
<nav>
{% if page.pagination.previous_page or page.pagination.next_page %}
{% if page.pagination.previous_page %}
<a href="{{ site.url }}{{ page.pagination.previous_page.url }}">Newer {$title}</a>
{% endif %}
{% if page.pagination.next_page %}
<a href="{{ site.url }}{{ page.pagination.next_page.url }}">Older {$title}</a>
{% endif %}
{% endif %}
</nav>
EOT;
}
}
Function Calls
None |
Stats
MD5 | fa80f0fe22a8b9187fe8282a7b53c395 |
Eval Count | 0 |
Decode Time | 90 ms |