mirror of
https://github.com/doctrine/doctrine-website.git
synced 2026-03-23 22:32:11 +01:00
Merging upstream/master
This commit is contained in:
1
LICENSE
1
LICENSE
@@ -17,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
"algolia/algoliasearch-client-php": "^1.27",
|
||||
"cache/doctrine-adapter": "^1.0",
|
||||
"doctrine/inflector": "^1.3",
|
||||
"doctrine/rst-parser": "dev-master",
|
||||
"doctrine/skeleton-mapper": "dev-master",
|
||||
"doctrine/skeleton-mapper": "^0.0.1",
|
||||
"doctrine/static-website-generator": "^0.0.1",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"knplabs/github-api": "^2.10",
|
||||
"php-http/guzzle6-adapter": "^1.1",
|
||||
|
||||
728
composer.lock
generated
728
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -2,11 +2,11 @@ parameters:
|
||||
doctrine.website.algolia.app_id: 'YVYTFT9XMW'
|
||||
doctrine.website.algolia.admin_api_key: '1234'
|
||||
|
||||
doctrine.website.projects_path: '%doctrine.website.root_dir%/projects'
|
||||
doctrine.website.docs_path: '%doctrine.website.root_dir%/docs'
|
||||
doctrine.website.source_path: '%doctrine.website.root_dir%/source'
|
||||
doctrine.website.webpack_build_path: '%doctrine.website.root_dir%/.webpack-build'
|
||||
doctrine.website.templates_path: '%doctrine.website.root_dir%/templates'
|
||||
doctrine.website.webpack_build_dir: '%doctrine.website.root_dir%/.webpack-build'
|
||||
doctrine.website.projects_dir: '%doctrine.website.root_dir%/projects'
|
||||
doctrine.website.docs_dir: '%doctrine.website.root_dir%/docs'
|
||||
doctrine.website.source_dir: '%doctrine.website.root_dir%/source'
|
||||
doctrine.website.templates_dir: '%doctrine.website.root_dir%/templates'
|
||||
|
||||
doctrine.website.title: Doctrine
|
||||
doctrine.website.subtitle: PHP Database Tools
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
parameters:
|
||||
doctrine.website.algolia.admin_api_key: 'abcd'
|
||||
doctrine.website.projects_path: '%doctrine.website.root_dir%/projects'
|
||||
doctrine.website.projects_dir: '%doctrine.website.root_dir%/projects'
|
||||
doctrine.website.github.http_token: 'abcd'
|
||||
|
||||
142
config/routes.yml
Normal file
142
config/routes.yml
Normal file
@@ -0,0 +1,142 @@
|
||||
parameters:
|
||||
doctrine.website.routes:
|
||||
homepage:
|
||||
path: /index.html
|
||||
controller: Doctrine\Website\Controllers\HomepageController::index
|
||||
defaults:
|
||||
title: Home
|
||||
menuSlug: home
|
||||
|
||||
atom:
|
||||
path: /atom.xml
|
||||
controller: Doctrine\Website\Controllers\AtomController::index
|
||||
|
||||
robots:
|
||||
path: /robots.txt
|
||||
|
||||
sitemap:
|
||||
path: /sitemap.xml
|
||||
controller: Doctrine\Website\Controllers\SitemapController::index
|
||||
|
||||
rst_examples:
|
||||
path: /rst-examples.html
|
||||
defaults:
|
||||
title: RST Example
|
||||
|
||||
blog:
|
||||
path: /blog/index.html
|
||||
controller: Doctrine\Website\Controllers\BlogController::index
|
||||
defaults:
|
||||
title: Blog
|
||||
menuSlug: blog
|
||||
|
||||
blog_archive:
|
||||
path: /blog/archive.html
|
||||
controller: Doctrine\Website\Controllers\BlogController::archive
|
||||
defaults:
|
||||
title: Blog Archive
|
||||
menuSlug: blog
|
||||
|
||||
blog_post:
|
||||
path: /{year}/{month}/{day}/{slug}.html
|
||||
controller: Doctrine\Website\Controllers\BlogController::view
|
||||
defaults:
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
|
||||
community:
|
||||
path: /community/index.html
|
||||
defaults:
|
||||
title: Community
|
||||
menuSlug: community
|
||||
|
||||
team_maintainers:
|
||||
path: /team/maintainers.html
|
||||
controller: Doctrine\Website\Controllers\TeamController::maintainers
|
||||
defaults:
|
||||
title: Doctrine Maintaiers
|
||||
menuSlug: team
|
||||
|
||||
team_contributors:
|
||||
path: /team/contributors.html
|
||||
controller: Doctrine\Website\Controllers\TeamController::contributors
|
||||
defaults:
|
||||
title: Doctrine Contributors
|
||||
menuSlug: team
|
||||
|
||||
team_contributor:
|
||||
path: /team/{github}.html
|
||||
controller: Doctrine\Website\Controllers\TeamController::contributor
|
||||
provider: Doctrine\Website\Requests\ContributorRequests::getContributors
|
||||
|
||||
contribute:
|
||||
path: /contribute/index.html
|
||||
defaults:
|
||||
title: Contribute
|
||||
menuSlug: development
|
||||
|
||||
contribute_maintainer:
|
||||
path: /contribute/maintainer/index.html
|
||||
defaults:
|
||||
title: Contribute to Website
|
||||
menuSlug: development
|
||||
|
||||
contribute_website:
|
||||
path: /contribute/website/index.html
|
||||
defaults:
|
||||
title: Contribute to Website
|
||||
menuSlug: development
|
||||
|
||||
policies:
|
||||
path: /policies.html
|
||||
defaults:
|
||||
title: Policies
|
||||
menuSlug: development
|
||||
|
||||
policies_deprecation:
|
||||
path: /policies/deprecation.html
|
||||
defaults:
|
||||
title: Deprecation Policy
|
||||
menuSlug: development
|
||||
|
||||
policies_releases:
|
||||
path: /policies/releases.html
|
||||
defaults:
|
||||
title: Release Policy
|
||||
menuSlug: development
|
||||
|
||||
policies_security:
|
||||
path: /policies/security.html
|
||||
defaults:
|
||||
title: Security Policy
|
||||
menuSlug: development
|
||||
|
||||
projects:
|
||||
path: /projects.html
|
||||
controller: Doctrine\Website\Controllers\ProjectController::index
|
||||
defaults:
|
||||
title: Projects
|
||||
menuSlug: projects
|
||||
|
||||
project:
|
||||
path: /projects/{slug}.html
|
||||
controller: Doctrine\Website\Controllers\ProjectController::view
|
||||
defaults:
|
||||
menuSlug: projects
|
||||
layout: project
|
||||
|
||||
project_docs_section:
|
||||
path: /projects/{docsSlug}/{language}/{docsVersion}/{section}.html
|
||||
controller: Doctrine\Website\Controllers\DocumentationController::view
|
||||
defaults:
|
||||
layout: documentation
|
||||
indexed: true
|
||||
menuSlug: projects
|
||||
docsPage: true
|
||||
requirements:
|
||||
section: .+
|
||||
|
||||
project_api_docs_page:
|
||||
path: /api/{slug}}/{docsVersion}/{page}.html
|
||||
requirements:
|
||||
section: .+
|
||||
@@ -7,19 +7,53 @@
|
||||
<defaults autowire="true" autoconfigure="true" public="false">
|
||||
<bind key="$rootDir">%doctrine.website.root_dir%</bind>
|
||||
<bind key="$env">%doctrine.website.env%</bind>
|
||||
<bind key="$projectsPath">%doctrine.website.projects_path%</bind>
|
||||
<bind key="$docsPath">%doctrine.website.docs_path%</bind>
|
||||
<bind key="$sourcePath">%doctrine.website.source_path%</bind>
|
||||
<bind key="$projectsDir">%doctrine.website.projects_dir%</bind>
|
||||
<bind key="$docsDir">%doctrine.website.docs_dir%</bind>
|
||||
<bind key="$sourceDir">%doctrine.website.source_dir%</bind>
|
||||
<bind key="$projectsData">%doctrine.website.projects_data%</bind>
|
||||
<bind key="$webpackBuildPath">%doctrine.website.webpack_build_path%</bind>
|
||||
<bind key="$webpackBuildDir">%doctrine.website.webpack_build_dir%</bind>
|
||||
<bind key="$teamMembers">%doctrine.website.team_members%</bind>
|
||||
<bind key="$templatesPath">%doctrine.website.templates_path%</bind>
|
||||
<bind key="$templatesDir">%doctrine.website.templates_dir%</bind>
|
||||
<bind key="$doctrineUsers">%doctrine.website.doctrine_users%</bind>
|
||||
<bind key="$projectIntegrationTypes">%doctrine.website.project_integration.types%</bind>
|
||||
<bind key="$routes">%doctrine.website.routes%</bind>
|
||||
</defaults>
|
||||
|
||||
<prototype namespace="Doctrine\Website\" resource="../lib/*" />
|
||||
|
||||
<prototype namespace="Doctrine\StaticWebsiteGenerator\" resource="../vendor/doctrine/static-website-generator/lib/*" />
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\MarkdownConverter">
|
||||
<argument type="service" id="Parsedown" />
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\ReStructuredTextConverter">
|
||||
<argument type="service" id="Doctrine\RST\Parser" />
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileBuilder">
|
||||
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRenderer" />
|
||||
<argument type="service" id="Symfony\Component\Filesystem\Filesystem" />
|
||||
<argument type="collection">
|
||||
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\MarkdownConverter" />
|
||||
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\ReStructuredTextConverter" />
|
||||
</argument>
|
||||
<argument type="collection">
|
||||
<argument>/\/api\//</argument>
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\Twig\StringTwigRenderer" autowire="false">
|
||||
<argument>%doctrine.website.templates_dir%</argument>
|
||||
<argument type="collection">
|
||||
<argument type="service" id="Doctrine\Website\Twig\MainExtension" />
|
||||
<argument type="service" id="Doctrine\Website\Twig\ProjectExtension" />
|
||||
<argument type="service" id="Doctrine\StaticWebsiteGenerator\Twig\RoutingExtension" />
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\Twig\TwigRenderer" alias="Doctrine\StaticWebsiteGenerator\Twig\StringTwigRenderer" />
|
||||
|
||||
<service id="Doctrine\Website\Application" autowire="true" public="true" />
|
||||
|
||||
<service id="Doctrine\Website\Projects\ProjectDataRepository" autowire="true" />
|
||||
@@ -33,6 +67,13 @@
|
||||
<argument type="service" id="Doctrine\Website\RST\Kernel" />
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRepository">
|
||||
<argument type="collection">
|
||||
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileFilesystemReader" />
|
||||
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRouteReader" />
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\RST\HTML\Kernel" autowire="true" />
|
||||
<service id="Github\Client">
|
||||
<call method="authenticate">
|
||||
@@ -52,11 +93,12 @@
|
||||
<service id="Parsedown" class="Parsedown" autowire="true" />
|
||||
<service id="Symfony\Component\Console\Application" autowire="true" />
|
||||
<service id="Symfony\Component\Filesystem\Filesystem" autowire="true" />
|
||||
<service id="Symfony\Component\HttpKernel\Controller\ArgumentResolver" autowire="true" />
|
||||
<service id="Doctrine\Common\Cache\FilesystemCache" autowire="false">
|
||||
<argument>%doctrine.website.cache_dir%</argument>
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\Website\Controller\ControllerProvider">
|
||||
<service id="Doctrine\StaticWebsiteGenerator\Controller\ControllerProvider">
|
||||
<argument type="collection">
|
||||
<argument type="service" id="Doctrine\Website\Controllers\AtomController" />
|
||||
<argument type="service" id="Doctrine\Website\Controllers\BlogController" />
|
||||
@@ -68,12 +110,18 @@
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\StaticWebsiteGenerator\Request\RequestCollectionProvider">
|
||||
<argument type="collection">
|
||||
<argument type="service" id="Doctrine\Website\Requests\ContributorRequests" />
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="AlgoliaSearch\Client">
|
||||
<argument>%doctrine.website.algolia.app_id%</argument>
|
||||
<argument>%doctrine.website.algolia.admin_api_key%</argument>
|
||||
</service>
|
||||
|
||||
<service id="Doctrine\Website\Site">
|
||||
<service id="Doctrine\StaticWebsiteGenerator\Site">
|
||||
<argument>%doctrine.website.title%</argument>
|
||||
<argument>%doctrine.website.subtitle%</argument>
|
||||
<argument>%doctrine.website.url%</argument>
|
||||
@@ -121,7 +169,7 @@
|
||||
<service id="Doctrine\Website\Repositories\BlogPostRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\BlogPosts" />
|
||||
<argument>Doctrine\Website\Model\BlogPost</argument>
|
||||
@@ -140,7 +188,7 @@
|
||||
<service id="Doctrine\Website\Repositories\ContributorRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\Contributors" />
|
||||
<argument>Doctrine\Website\Model\Contributor</argument>
|
||||
@@ -159,7 +207,7 @@
|
||||
<service id="Doctrine\Website\Repositories\DoctrineUserRepository" autowire="false" public="true">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\DoctrineUsers" />
|
||||
<argument>Doctrine\Website\Model\DoctrineUser</argument>
|
||||
@@ -178,7 +226,7 @@
|
||||
<service id="Doctrine\Website\Repositories\ProjectRepository" autowire="false" public="true">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\Projects" />
|
||||
<argument>Doctrine\Website\Model\Project</argument>
|
||||
@@ -197,7 +245,7 @@
|
||||
<service id="Doctrine\Website\Repositories\ProjectContributorRepository" autowire="false" public="true">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\ProjectContributors" />
|
||||
<argument>Doctrine\Website\Model\ProjectContributor</argument>
|
||||
@@ -216,7 +264,7 @@
|
||||
<service id="Doctrine\Website\Repositories\SitemapPageRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\SitemapPages" />
|
||||
<argument>Doctrine\Website\Model\SitemapPage</argument>
|
||||
@@ -235,7 +283,7 @@
|
||||
<service id="Doctrine\Website\Repositories\TeamMemberRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service">
|
||||
<service class="Doctrine\Website\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<service class="Doctrine\SkeletonMapper\DataSource\DataSourceObjectDataRepository" autowire="false">
|
||||
<argument type="service" id="Doctrine\SkeletonMapper\ObjectManager" />
|
||||
<argument type="service" id="Doctrine\Website\DataSources\TeamMembers" />
|
||||
<argument>Doctrine\Website\Model\TeamMember</argument>
|
||||
|
||||
@@ -11,6 +11,7 @@ use Doctrine\Website\Commands\DeployCommand;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\Console\Application as BaseApplication;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||
@@ -52,6 +53,15 @@ class Application
|
||||
|
||||
public function run(InputInterface $input) : int
|
||||
{
|
||||
$inputOption = new InputOption(
|
||||
'env',
|
||||
'e',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The environment.',
|
||||
'dev'
|
||||
);
|
||||
$this->application->getDefinition()->addOption($inputOption);
|
||||
|
||||
$this->application->add($this->buildDocsCommand);
|
||||
$this->application->add($this->buildWebsiteCommand);
|
||||
$this->application->add($this->clearBuildCacheCommand);
|
||||
@@ -75,6 +85,7 @@ class Application
|
||||
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
|
||||
$loader->load('projects.yml');
|
||||
$loader->load('team_members.yml');
|
||||
$loader->load('routes.yml');
|
||||
|
||||
$loader->load(sprintf('config_%s.yml', $env));
|
||||
|
||||
|
||||
@@ -13,24 +13,24 @@ use function realpath;
|
||||
class AssetIntegrityGenerator
|
||||
{
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
private $sourceDir;
|
||||
|
||||
/** @var string */
|
||||
private $webpackBuildPath;
|
||||
private $webpackBuildDir;
|
||||
|
||||
/** @var string[] */
|
||||
private $cache = [];
|
||||
|
||||
public function __construct(string $sourcePath, string $webpackBuildPath)
|
||||
public function __construct(string $sourceDir, string $webpackBuildDir)
|
||||
{
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->webpackBuildPath = $webpackBuildPath;
|
||||
$this->sourceDir = $sourceDir;
|
||||
$this->webpackBuildDir = $webpackBuildDir;
|
||||
}
|
||||
|
||||
public function getAssetIntegrity(string $path, string $rootPath = null) : string
|
||||
{
|
||||
if (! isset($this->cache[$path])) {
|
||||
$contents = $this->getFileContents($path, $rootPath ?? $this->sourcePath);
|
||||
$contents = $this->getFileContents($path, $rootPath ?? $this->sourceDir);
|
||||
|
||||
$this->cache[$path] = $this->buildAssetIntegrityString($contents);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class AssetIntegrityGenerator
|
||||
|
||||
public function getWebpackAssetIntegrity(string $path) : string
|
||||
{
|
||||
return $this->getAssetIntegrity($path, $this->webpackBuildPath);
|
||||
return $this->getAssetIntegrity($path, $this->webpackBuildDir);
|
||||
}
|
||||
|
||||
private function getFileContents(string $path, string $rootPath) : string
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Builder;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function in_array;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use function strtotime;
|
||||
|
||||
class SourceFile
|
||||
{
|
||||
private const TWIG_EXTENSIONS = ['html', 'md', 'rst', 'xml', 'txt'];
|
||||
|
||||
private const NEEDS_LAYOUT_EXTENSIONS = ['html', 'md', 'rst'];
|
||||
|
||||
private const MARKDOWN_EXTENSION = 'md';
|
||||
|
||||
private const RESTRUCTURED_TEXT_EXTENSION = 'rst';
|
||||
|
||||
/** @var string */
|
||||
private $extension;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
|
||||
/** @var string */
|
||||
private $writePath;
|
||||
|
||||
/** @var string */
|
||||
private $contents;
|
||||
|
||||
/** @var SourceFileParameters */
|
||||
private $parameters;
|
||||
|
||||
public function __construct(
|
||||
string $extension,
|
||||
string $sourcePath,
|
||||
string $writePath,
|
||||
string $contents,
|
||||
SourceFileParameters $parameters
|
||||
) {
|
||||
$this->extension = $extension;
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->writePath = $writePath;
|
||||
$this->contents = $contents;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
public function getSourcePath() : string
|
||||
{
|
||||
return $this->sourcePath;
|
||||
}
|
||||
|
||||
public function getWritePath() : string
|
||||
{
|
||||
return $this->writePath;
|
||||
}
|
||||
|
||||
public function getUrl() : string
|
||||
{
|
||||
return (string) $this->parameters->getParameter('url');
|
||||
}
|
||||
|
||||
public function getDate() : DateTimeImmutable
|
||||
{
|
||||
$e = explode('/', $this->getUrl());
|
||||
|
||||
if (count($e) < 4) {
|
||||
return new DateTimeImmutable();
|
||||
}
|
||||
|
||||
$date = strtotime(sprintf('%s/%s/%s', $e[1], $e[2], $e[3]));
|
||||
|
||||
if ($date === false) {
|
||||
return new DateTimeImmutable();
|
||||
}
|
||||
|
||||
return (new DateTimeImmutable())->setTimestamp($date);
|
||||
}
|
||||
|
||||
public function getExtension() : string
|
||||
{
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
public function isMarkdown() : bool
|
||||
{
|
||||
return $this->getExtension() === self::MARKDOWN_EXTENSION;
|
||||
}
|
||||
|
||||
public function isRestructuredText() : bool
|
||||
{
|
||||
return $this->getExtension() === self::RESTRUCTURED_TEXT_EXTENSION;
|
||||
}
|
||||
|
||||
public function isTwig() : bool
|
||||
{
|
||||
return in_array($this->getExtension(), self::TWIG_EXTENSIONS, true) && $this->isApiDocs() === false;
|
||||
}
|
||||
|
||||
public function isLayoutNeeded() : bool
|
||||
{
|
||||
return in_array($this->getExtension(), self::NEEDS_LAYOUT_EXTENSIONS, true);
|
||||
}
|
||||
|
||||
public function isApiDocs() : bool
|
||||
{
|
||||
return strpos($this->getUrl(), '/api/') === 0;
|
||||
}
|
||||
|
||||
public function getContents() : string
|
||||
{
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
public function getParameters() : SourceFileParameters
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameter(string $key)
|
||||
{
|
||||
return $this->parameters->getParameter($key);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Builder;
|
||||
|
||||
use Doctrine\RST\Parser as RSTParser;
|
||||
use Parsedown;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
class SourceFileBuilder
|
||||
{
|
||||
/** @var SourceFileRenderer */
|
||||
private $sourceFileRenderer;
|
||||
|
||||
/** @var Filesystem */
|
||||
private $filesystem;
|
||||
|
||||
/** @var Parsedown */
|
||||
private $parsedown;
|
||||
|
||||
/** @var RSTParser */
|
||||
private $rstParser;
|
||||
|
||||
public function __construct(
|
||||
SourceFileRenderer $sourceFileRenderer,
|
||||
Filesystem $filesystem,
|
||||
Parsedown $parsedown,
|
||||
RSTParser $rstParser
|
||||
) {
|
||||
$this->sourceFileRenderer = $sourceFileRenderer;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->parsedown = $parsedown;
|
||||
$this->rstParser = $rstParser;
|
||||
}
|
||||
|
||||
public function buildFile(SourceFile $sourceFile, string $buildDir) : void
|
||||
{
|
||||
$parsedFile = $this->parseFile($sourceFile);
|
||||
|
||||
if ($sourceFile->isTwig()) {
|
||||
$parsedFile = $this->sourceFileRenderer->render(
|
||||
$sourceFile,
|
||||
$parsedFile
|
||||
);
|
||||
}
|
||||
|
||||
$this->filesystem->dumpFile($sourceFile->getWritePath(), $parsedFile);
|
||||
}
|
||||
|
||||
private function parseFile(SourceFile $sourceFile) : string
|
||||
{
|
||||
$contents = $sourceFile->getContents();
|
||||
|
||||
if ($sourceFile->isMarkdown()) {
|
||||
return $this->parsedown->text($contents);
|
||||
}
|
||||
|
||||
if ($sourceFile->isRestructuredText()) {
|
||||
return $this->rstParser->parse($contents)->render();
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Builder;
|
||||
|
||||
class SourceFileParameters
|
||||
{
|
||||
/** @var mixed[] */
|
||||
private $parameters = [];
|
||||
|
||||
/**
|
||||
* @param mixed[] $parameters
|
||||
*/
|
||||
public function __construct(array $parameters)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getAll() : array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameter(string $key)
|
||||
{
|
||||
return $this->parameters[$key] ?? null;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Builder;
|
||||
|
||||
use Doctrine\Website\Controller\ControllerExecutor;
|
||||
use Doctrine\Website\Site;
|
||||
use Doctrine\Website\Twig\TwigRenderer;
|
||||
use function preg_match_all;
|
||||
use function str_replace;
|
||||
|
||||
class SourceFileRenderer
|
||||
{
|
||||
/** @var ControllerExecutor */
|
||||
private $controllerExecutor;
|
||||
|
||||
/** @var TwigRenderer */
|
||||
private $twigRenderer;
|
||||
|
||||
/** @var Site */
|
||||
private $site;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
|
||||
public function __construct(
|
||||
ControllerExecutor $controllerExecutor,
|
||||
TwigRenderer $twigRenderer,
|
||||
Site $site,
|
||||
string $sourcePath
|
||||
) {
|
||||
$this->controllerExecutor = $controllerExecutor;
|
||||
$this->twigRenderer = $twigRenderer;
|
||||
$this->site = $site;
|
||||
$this->sourcePath = $sourcePath;
|
||||
}
|
||||
|
||||
public function render(SourceFile $sourceFile, string $contents) : string
|
||||
{
|
||||
$template = $this->prepareTemplate($sourceFile, $contents);
|
||||
|
||||
$pageParameters = $this->preparePageParameters($sourceFile);
|
||||
|
||||
$parameters = [
|
||||
'page' => $pageParameters,
|
||||
'site' => $this->site,
|
||||
];
|
||||
|
||||
if (isset($parameters['page']['controller'])) {
|
||||
$controllerParameters = $this->controllerExecutor->execute($sourceFile);
|
||||
|
||||
$parameters += $controllerParameters;
|
||||
}
|
||||
|
||||
return $this->twigRenderer->render($template, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function preparePageParameters(SourceFile $sourceFile) : array
|
||||
{
|
||||
return $sourceFile->getParameters()->getAll() + [
|
||||
'date' => $sourceFile->getDate(),
|
||||
'sourceFile' => str_replace($this->sourcePath, '/source', $sourceFile->getSourcePath()),
|
||||
];
|
||||
}
|
||||
|
||||
private function prepareTemplate(SourceFile $sourceFile, string $contents) : string
|
||||
{
|
||||
if ($sourceFile->isLayoutNeeded()) {
|
||||
if ($contents !== '') {
|
||||
$regex = '/{%\s+block\s+(\w+)\s+%}(.*?){%\s+endblock\s+%}/si';
|
||||
|
||||
if (preg_match_all($regex, $contents, $matches) === 0) {
|
||||
$contents = '{% block content %}' . $contents . '{% endblock %}';
|
||||
}
|
||||
}
|
||||
|
||||
$contents = '{% extends "layouts/' . $sourceFile->getParameter('layout') . '.html.twig" %}' . $contents;
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Builder;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use function assert;
|
||||
use function end;
|
||||
use function explode;
|
||||
use function file_get_contents;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function preg_match;
|
||||
use function preg_replace;
|
||||
use function str_replace;
|
||||
use function strrpos;
|
||||
use function substr;
|
||||
|
||||
class SourceFileRepository
|
||||
{
|
||||
/** @var string */
|
||||
private $rootDir;
|
||||
|
||||
public function __construct(string $rootDir)
|
||||
{
|
||||
$this->rootDir = $rootDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SourceFile[]
|
||||
*/
|
||||
public function getFiles(string $buildDir, string $inPath = 'source') : array
|
||||
{
|
||||
$finder = new Finder();
|
||||
|
||||
$finder
|
||||
->in($this->rootDir . '/' . $inPath)
|
||||
->files();
|
||||
|
||||
$files = [];
|
||||
|
||||
foreach ($finder as $splFileInfo) {
|
||||
$path = $splFileInfo->getRealPath();
|
||||
assert(is_string($path));
|
||||
|
||||
$contents = file_get_contents($path);
|
||||
assert(is_string($contents));
|
||||
|
||||
$extension = $this->getExtension($path);
|
||||
|
||||
$writePath = $this->getWritePath($buildDir, $path, $extension);
|
||||
|
||||
$sourceFileParameters = $this->createSourceFileParameters(
|
||||
$buildDir,
|
||||
$writePath,
|
||||
$contents
|
||||
);
|
||||
|
||||
$writePath = $buildDir . $sourceFileParameters->getParameter('url');
|
||||
|
||||
$contents = $this->stripFileParameters($contents);
|
||||
|
||||
$files[] = new SourceFile(
|
||||
$extension,
|
||||
$path,
|
||||
$writePath,
|
||||
$contents,
|
||||
$sourceFileParameters
|
||||
);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
private function getWritePath(string $buildDir, string $path, string $extension) : string
|
||||
{
|
||||
$writePath = $buildDir . str_replace($this->rootDir . '/source', '', $path);
|
||||
|
||||
if (in_array($extension, ['md', 'rst'], true)) {
|
||||
$writePath = substr($writePath, 0, (int) strrpos($writePath, '.')) . '.html';
|
||||
}
|
||||
|
||||
return $writePath;
|
||||
}
|
||||
|
||||
private function getExtension(string $path) : string
|
||||
{
|
||||
$e = explode('.', $path);
|
||||
|
||||
return end($e);
|
||||
}
|
||||
|
||||
private function stripFileParameters(string $contents) : string
|
||||
{
|
||||
return preg_replace('/^\s*(?:---[\s]*[\r\n]+)(.*?)(?:---[\s]*[\r\n]+)(.*?)$/s', '$2', $contents);
|
||||
}
|
||||
|
||||
private function createSourceFileParameters(
|
||||
string $buildDir,
|
||||
string $writePath,
|
||||
string $string
|
||||
) : SourceFileParameters {
|
||||
$parameters = [];
|
||||
|
||||
if (preg_match('/^\s*(?:---[\s]*[\r\n]+)(.*?)(?:---[\s]*[\r\n]+)(.*?)$/s', $string, $matches) > 0) {
|
||||
if (preg_match('/^(\s*[-]+\s*|\s*)$/', $matches[1]) === 0) {
|
||||
$parameters = Yaml::parse($matches[1], 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (! isset($parameters['layout'])) {
|
||||
$parameters['layout'] = 'default';
|
||||
}
|
||||
|
||||
$parameters['url'] = $this->getUrl($buildDir, $writePath, $parameters);
|
||||
|
||||
return new SourceFileParameters($parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $parameters
|
||||
*/
|
||||
private function getUrl(string $buildDir, string $writePath, array $parameters) : string
|
||||
{
|
||||
$permalink = $parameters['permalink'] ?? '';
|
||||
|
||||
if ($permalink !== '' && $permalink !== 'none') {
|
||||
return $permalink;
|
||||
}
|
||||
|
||||
return str_replace($buildDir, '', $writePath);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,9 @@ use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use function assert;
|
||||
use function is_bool;
|
||||
use function is_string;
|
||||
|
||||
class BuildDocsCommand extends Command
|
||||
{
|
||||
@@ -31,13 +34,15 @@ class BuildDocsCommand extends Command
|
||||
'project',
|
||||
null,
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The project to build the docs for.'
|
||||
'The project to build the docs for.',
|
||||
''
|
||||
)
|
||||
->addOption(
|
||||
'v',
|
||||
null,
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The project version to build the docs for.'
|
||||
'The project version to build the docs for.',
|
||||
''
|
||||
)
|
||||
->addOption(
|
||||
'api',
|
||||
@@ -56,22 +61,25 @@ class BuildDocsCommand extends Command
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Sync git repositories before building.'
|
||||
)
|
||||
->addOption(
|
||||
'env',
|
||||
'e',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The environment.'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) : int
|
||||
{
|
||||
$projectToBuild = (string) $input->getOption('project');
|
||||
$versionToBuild = (string) $input->getOption('v');
|
||||
$buildApiDocs = (bool) $input->getOption('api');
|
||||
$buildSearchIndexes = (bool) $input->getOption('search');
|
||||
$syncGit = (bool) $input->getOption('sync-git');
|
||||
$projectToBuild = $input->getOption('project');
|
||||
assert(is_string($projectToBuild));
|
||||
|
||||
$versionToBuild = $input->getOption('v');
|
||||
assert(is_string($versionToBuild));
|
||||
|
||||
$buildApiDocs = $input->getOption('api');
|
||||
assert(is_bool($buildApiDocs));
|
||||
|
||||
$buildSearchIndexes = $input->getOption('search');
|
||||
assert(is_bool($buildSearchIndexes));
|
||||
|
||||
$syncGit = $input->getOption('sync-git');
|
||||
assert(is_bool($syncGit));
|
||||
|
||||
$this->buildDocs->build(
|
||||
$output,
|
||||
|
||||
@@ -11,9 +11,12 @@ 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 function assert;
|
||||
use function in_array;
|
||||
use function ini_set;
|
||||
use function is_bool;
|
||||
use function is_dir;
|
||||
use function is_string;
|
||||
use function mkdir;
|
||||
use function realpath;
|
||||
use function sprintf;
|
||||
@@ -57,12 +60,6 @@ class BuildWebsiteCommand extends Command
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Publish the build to GitHub Pages.'
|
||||
)
|
||||
->addOption(
|
||||
'env',
|
||||
'e',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The environment.'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,13 +67,15 @@ class BuildWebsiteCommand extends Command
|
||||
{
|
||||
ini_set('memory_limit', '1024M');
|
||||
|
||||
$publish = (bool) $input->getOption('publish');
|
||||
$publish = $input->getOption('publish');
|
||||
assert(is_bool($publish));
|
||||
|
||||
if ($publish && ! in_array($this->env, WebsiteBuilder::PUBLISHABLE_ENVS, true)) {
|
||||
throw new InvalidArgumentException(sprintf('You cannot publish the "%s" environment.', $this->env));
|
||||
}
|
||||
|
||||
$buildDir = $input->getArgument('build-dir');
|
||||
assert(is_string($buildDir));
|
||||
|
||||
if (! is_dir($buildDir)) {
|
||||
mkdir($buildDir, 0777, true);
|
||||
|
||||
@@ -11,7 +11,9 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use function array_filter;
|
||||
use function assert;
|
||||
use function glob;
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
|
||||
class ClearBuildCacheCommand extends Command
|
||||
@@ -54,6 +56,7 @@ class ClearBuildCacheCommand extends Command
|
||||
protected function execute(InputInterface $input, OutputInterface $output) : int
|
||||
{
|
||||
$buildDir = $input->getArgument('build-dir');
|
||||
assert(is_string($buildDir));
|
||||
|
||||
// clear build directory
|
||||
$remove = [$buildDir];
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Doctrine\Website\Commands;
|
||||
use Doctrine\Website\Deployer;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class DeployCommand extends Command
|
||||
@@ -26,13 +25,7 @@ class DeployCommand extends Command
|
||||
{
|
||||
$this
|
||||
->setName('deploy')
|
||||
->setDescription('Deploy the Doctrine website.')
|
||||
->addOption(
|
||||
'env',
|
||||
'e',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'The environment.'
|
||||
);
|
||||
->setDescription('Deploy the Doctrine website.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) : int
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controller;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use ReflectionClass;
|
||||
use RuntimeException;
|
||||
use function sprintf;
|
||||
|
||||
class ControllerExecutor
|
||||
{
|
||||
/** @var ControllerProvider */
|
||||
private $controllerProvider;
|
||||
|
||||
public function __construct(ControllerProvider $controllerProvider)
|
||||
{
|
||||
$this->controllerProvider = $controllerProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function execute(SourceFile $sourceFile) : array
|
||||
{
|
||||
[$className, $methodName] = $sourceFile->getParameter('controller');
|
||||
|
||||
$controller = $this->controllerProvider->getController($className);
|
||||
|
||||
$reflectionMethod = (new ReflectionClass($controller))->getMethod($methodName);
|
||||
|
||||
$controllerResult = $reflectionMethod->invokeArgs($controller, [$sourceFile]);
|
||||
|
||||
if (! $controllerResult instanceof ControllerResult) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Controller %s did not return a %s instance.',
|
||||
$className,
|
||||
ControllerResult::class
|
||||
));
|
||||
}
|
||||
|
||||
return $controllerResult->getResult();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controller;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use function get_class;
|
||||
use function sprintf;
|
||||
|
||||
class ControllerProvider
|
||||
{
|
||||
/** @var object[] */
|
||||
private $controllers;
|
||||
|
||||
/**
|
||||
* @param object[] $controllers
|
||||
*/
|
||||
public function __construct(array $controllers)
|
||||
{
|
||||
foreach ($controllers as $controller) {
|
||||
$this->controllers[get_class($controller)] = $controller;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object
|
||||
*/
|
||||
public function getController(string $className)
|
||||
{
|
||||
if (! isset($this->controllers[$className])) {
|
||||
throw new InvalidArgumentException(sprintf('Could not find controller class %s', $className));
|
||||
}
|
||||
|
||||
return $this->controllers[$className];
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controller;
|
||||
|
||||
class ControllerResult
|
||||
{
|
||||
/** @var mixed[] */
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* @param mixed[] $result
|
||||
*/
|
||||
public function __construct(array $result)
|
||||
{
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getResult() : array
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\BlogPostRepository;
|
||||
|
||||
class AtomController
|
||||
@@ -18,9 +17,9 @@ class AtomController
|
||||
$this->blogPostRepository = $blogPostRepository;
|
||||
}
|
||||
|
||||
public function index(SourceFile $sourceFile) : ControllerResult
|
||||
public function index() : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'blogPosts' => $this->blogPostRepository->findPaginated(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\BlogPostRepository;
|
||||
|
||||
class BlogController
|
||||
@@ -18,24 +17,24 @@ class BlogController
|
||||
$this->blogPostRepository = $blogPostRepository;
|
||||
}
|
||||
|
||||
public function index(SourceFile $sourceFile) : ControllerResult
|
||||
public function index() : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'blogPosts' => $this->blogPostRepository->findPaginated(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function archive(SourceFile $sourceFile) : ControllerResult
|
||||
public function archive() : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'blogPosts' => $this->blogPostRepository->findAll(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function view(SourceFile $sourceFile) : ControllerResult
|
||||
public function view(string $slug) : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
'blogPost' => $this->blogPostRepository->find($sourceFile->getParameter('url')),
|
||||
return new Response([
|
||||
'blogPost' => $this->blogPostRepository->find($slug),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\ProjectRepository;
|
||||
|
||||
class DocumentationController
|
||||
@@ -18,13 +17,13 @@ class DocumentationController
|
||||
$this->projectRepository = $projectRepository;
|
||||
}
|
||||
|
||||
public function view(SourceFile $sourceFile) : ControllerResult
|
||||
public function view(string $docsSlug, string $docsVersion) : Response
|
||||
{
|
||||
$project = $this->projectRepository->findOneByDocsSlug($sourceFile->getParameter('docsSlug'));
|
||||
$project = $this->projectRepository->findOneByDocsSlug($docsSlug);
|
||||
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'project' => $project,
|
||||
'projectVersion' => $project->getVersion($sourceFile->getParameter('docsVersion')),
|
||||
'projectVersion' => $project->getVersion($docsVersion),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\BlogPostRepository;
|
||||
use Doctrine\Website\Repositories\DoctrineUserRepository;
|
||||
use Doctrine\Website\Repositories\ProjectRepository;
|
||||
@@ -31,13 +30,13 @@ class HomepageController
|
||||
$this->doctrineUserRepository = $doctrineUserRepository;
|
||||
}
|
||||
|
||||
public function index(SourceFile $sourceFile) : ControllerResult
|
||||
public function index() : Response
|
||||
{
|
||||
$blogPosts = $this->blogPostRepository->findPaginated(1, 10);
|
||||
$primaryProjects = $this->projectRepository->findPrimaryProjects();
|
||||
$doctrineUsers = $this->doctrineUserRepository->findAll();
|
||||
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'blogPosts' => $blogPosts,
|
||||
'primaryProjects' => $primaryProjects,
|
||||
'doctrineUsers' => $doctrineUsers,
|
||||
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\ProjectContributorRepository;
|
||||
use Doctrine\Website\Repositories\ProjectRepository;
|
||||
|
||||
@@ -25,9 +24,9 @@ class ProjectController
|
||||
$this->projectContributorRepository = $projectContributorRepository;
|
||||
}
|
||||
|
||||
public function index(SourceFile $sourceFile) : ControllerResult
|
||||
public function index() : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'primaryProjects' => $this->projectRepository->findPrimaryProjects(),
|
||||
'inactiveProjects' => $this->projectRepository->findInactiveProjects(),
|
||||
'archivedProjects' => $this->projectRepository->findArchivedProjects(),
|
||||
@@ -35,11 +34,11 @@ class ProjectController
|
||||
]);
|
||||
}
|
||||
|
||||
public function view(SourceFile $sourceFile) : ControllerResult
|
||||
public function view(string $docsSlug) : Response
|
||||
{
|
||||
$project = $this->projectRepository->findOneByDocsSlug($sourceFile->getParameter('docsSlug'));
|
||||
$project = $this->projectRepository->findOneByDocsSlug($docsSlug);
|
||||
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'project' => $project,
|
||||
'integrationProjects' => $this->projectRepository->findProjectIntegrations($project),
|
||||
'maintainers' => $this->projectContributorRepository->findMaintainersByProject($project),
|
||||
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\SitemapPageRepository;
|
||||
|
||||
class SitemapController
|
||||
@@ -18,8 +17,8 @@ class SitemapController
|
||||
$this->sitemapPageRepository = $sitemapPageRepository;
|
||||
}
|
||||
|
||||
public function index(SourceFile $sourceFile) : ControllerResult
|
||||
public function index() : Response
|
||||
{
|
||||
return new ControllerResult(['pages' => $this->sitemapPageRepository->findAll()]);
|
||||
return new Response(['pages' => $this->sitemapPageRepository->findAll()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Controllers;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFile;
|
||||
use Doctrine\Website\Controller\ControllerResult;
|
||||
use Doctrine\StaticWebsiteGenerator\Controller\Response;
|
||||
use Doctrine\Website\Repositories\ContributorRepository;
|
||||
|
||||
class TeamController
|
||||
@@ -18,17 +17,27 @@ class TeamController
|
||||
$this->contributorRepository = $contributorRepository;
|
||||
}
|
||||
|
||||
public function maintainers(SourceFile $sourceFile) : ControllerResult
|
||||
public function maintainers() : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'contributors' => $this->contributorRepository->findMaintainers(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function contributors(SourceFile $sourceFile) : ControllerResult
|
||||
public function contributors() : Response
|
||||
{
|
||||
return new ControllerResult([
|
||||
return new Response([
|
||||
'contributors' => $this->contributorRepository->findContributors(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function contributor(string $github) : Response
|
||||
{
|
||||
$contributor = $this->contributorRepository->findOneByGithub($github);
|
||||
|
||||
return new Response(
|
||||
['contributor' => $contributor],
|
||||
'/team/member.html.twig'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSource;
|
||||
|
||||
use function in_array;
|
||||
|
||||
class CriteriaMatcher
|
||||
{
|
||||
/** @var mixed[] */
|
||||
private $criteria;
|
||||
|
||||
/** @var mixed[] */
|
||||
private $row;
|
||||
|
||||
/**
|
||||
* @param mixed[] $criteria
|
||||
* @param mixed[] $row
|
||||
*/
|
||||
public function __construct(array $criteria, array $row)
|
||||
{
|
||||
$this->criteria = $criteria;
|
||||
$this->row = $row;
|
||||
}
|
||||
|
||||
public function matches() : bool
|
||||
{
|
||||
$matches = true;
|
||||
|
||||
foreach ($this->criteria as $key => $value) {
|
||||
if ($this->criteriaElementMatches($key, $value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$matches = false;
|
||||
}
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function criteriaElementMatches(string $key, $value) : bool
|
||||
{
|
||||
if (isset($value['$contains'])) {
|
||||
if ($this->contains($key, $value)) {
|
||||
return true;
|
||||
}
|
||||
} elseif ($this->equals($key, $value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $value
|
||||
*/
|
||||
private function contains(string $key, array $value) : bool
|
||||
{
|
||||
return isset($this->row[$key]) && in_array($value['$contains'], $this->row[$key], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function equals(string $key, $value) : bool
|
||||
{
|
||||
return isset($this->row[$key]) && $this->row[$key] === $value;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSource;
|
||||
|
||||
interface DataSource
|
||||
{
|
||||
/**
|
||||
* @return mixed[][]
|
||||
*/
|
||||
public function getSourceRows() : array;
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSource;
|
||||
|
||||
use Doctrine\SkeletonMapper\DataRepository\BasicObjectDataRepository;
|
||||
use Doctrine\SkeletonMapper\ObjectManagerInterface;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
use function usort;
|
||||
|
||||
class DataSourceObjectDataRepository extends BasicObjectDataRepository
|
||||
{
|
||||
/** @var DataSource */
|
||||
private $dataSource;
|
||||
|
||||
/** @var mixed[][]|null */
|
||||
private $sourceRows;
|
||||
|
||||
public function __construct(
|
||||
ObjectManagerInterface $objectManager,
|
||||
DataSource $dataSource,
|
||||
string $className
|
||||
) {
|
||||
parent::__construct($objectManager, $className);
|
||||
$this->dataSource = $dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[][]
|
||||
*/
|
||||
public function findAll() : array
|
||||
{
|
||||
return $this->getSourceRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $criteria
|
||||
* @param mixed[] $orderBy
|
||||
*
|
||||
* @return mixed[][]
|
||||
*/
|
||||
public function findBy(
|
||||
array $criteria,
|
||||
?array $orderBy = null,
|
||||
?int $limit = null,
|
||||
?int $offset = null
|
||||
) : array {
|
||||
$rows = [];
|
||||
|
||||
foreach ($this->getSourceRows() as $row) {
|
||||
if (! $this->matches($criteria, $row)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
if ($orderBy !== null && $orderBy !== []) {
|
||||
$rows = $this->sort($rows, $orderBy);
|
||||
}
|
||||
|
||||
if ($limit !== null || $offset !== null) {
|
||||
return $this->slice($rows, $limit, $offset);
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $criteria
|
||||
*
|
||||
* @return mixed[]|null
|
||||
*/
|
||||
public function findOneBy(array $criteria) : ?array
|
||||
{
|
||||
foreach ($this->getSourceRows() as $row) {
|
||||
if ($this->matches($criteria, $row)) {
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed[] $criteria
|
||||
* @param mixed[] $row
|
||||
*/
|
||||
private function matches(array $criteria, array $row) : bool
|
||||
{
|
||||
return (new CriteriaMatcher($criteria, $row))->matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[][] $rows
|
||||
* @param string[] $orderBy
|
||||
*
|
||||
* @return mixed[][] $rows
|
||||
*/
|
||||
private function sort(array $rows, array $orderBy) : array
|
||||
{
|
||||
usort($rows, new Sorter($orderBy));
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[][] $rows
|
||||
*
|
||||
* @return mixed[][] $rows
|
||||
*/
|
||||
private function slice(array $rows, ?int $limit, ?int $offset) : array
|
||||
{
|
||||
if ($limit === null) {
|
||||
$limit = count($rows);
|
||||
}
|
||||
|
||||
if ($offset === null) {
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
return array_slice($rows, $offset, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[][]
|
||||
*/
|
||||
private function getSourceRows() : array
|
||||
{
|
||||
if ($this->sourceRows === null) {
|
||||
$this->sourceRows = $this->dataSource->getSourceRows();
|
||||
}
|
||||
|
||||
return $this->sourceRows;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSource;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use function count;
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
use function strtolower;
|
||||
|
||||
class Sorter
|
||||
{
|
||||
private const ORDER_ASC = 'asc';
|
||||
private const ORDER_DESC = 'desc';
|
||||
|
||||
/** @var int */
|
||||
private $level = 0;
|
||||
|
||||
/** @var string[] */
|
||||
private $fields;
|
||||
|
||||
/** @var int[] */
|
||||
private $orders;
|
||||
|
||||
/**
|
||||
* @param string[] $orderBy
|
||||
*/
|
||||
public function __construct(array $orderBy)
|
||||
{
|
||||
if ($orderBy === []) {
|
||||
throw new InvalidArgumentException('The Sorter class does not accept an empty $orderBy');
|
||||
}
|
||||
|
||||
foreach ($orderBy as $field => $order) {
|
||||
$this->fields[] = $field;
|
||||
$this->orders[] = $this->getOrder($order);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $a
|
||||
* @param mixed[] $b
|
||||
*/
|
||||
public function __invoke(array $a, array $b) : int
|
||||
{
|
||||
$returnVal = 0;
|
||||
$comparisonField = $this->fields[$this->level];
|
||||
$order = $this->orders[$this->level];
|
||||
$aComparisonField = $this->getComparisonField($a, $comparisonField);
|
||||
$bComparisonField = $this->getComparisonField($b, $comparisonField);
|
||||
|
||||
$comparisonResult = $aComparisonField <=> $bComparisonField;
|
||||
|
||||
if ($comparisonResult !== 0) {
|
||||
$returnVal = $comparisonResult;
|
||||
} else {
|
||||
if ($this->level < count($this->fields) - 1) {
|
||||
$this->level++;
|
||||
|
||||
return $this->__invoke($a, $b);
|
||||
}
|
||||
}
|
||||
|
||||
$returnVal *= $order;
|
||||
|
||||
$this->level = 0;
|
||||
|
||||
return $returnVal;
|
||||
}
|
||||
|
||||
private function getOrder(string $order) : int
|
||||
{
|
||||
$lowercaseOrder = strtolower($order);
|
||||
|
||||
if ($lowercaseOrder === self::ORDER_ASC) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($lowercaseOrder === self::ORDER_DESC) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'$order value of %s is not accepted. Only a value of asc or desc is allowed.',
|
||||
$order
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getComparisonField(array $item, string $field)
|
||||
{
|
||||
if (! isset($item[$field])) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to find comparison field %s', $field));
|
||||
}
|
||||
|
||||
$value = $item[$field];
|
||||
|
||||
return is_string($value) ? strtolower($value) : $value;
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,17 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFileRepository;
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use function array_reverse;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
use Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileFilesystemReader;
|
||||
|
||||
class BlogPosts implements DataSource
|
||||
{
|
||||
/** @var SourceFileRepository */
|
||||
private $sourceFileRepository;
|
||||
/** @var SourceFileFilesystemReader */
|
||||
private $sourceFileFilesystemReader;
|
||||
|
||||
public function __construct(SourceFileRepository $sourceFileRepository)
|
||||
public function __construct(SourceFileFilesystemReader $sourceFileFilesystemReader)
|
||||
{
|
||||
$this->sourceFileRepository = $sourceFileRepository;
|
||||
$this->sourceFileFilesystemReader = $sourceFileFilesystemReader;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,15 +22,15 @@ class BlogPosts implements DataSource
|
||||
*/
|
||||
public function getSourceRows() : array
|
||||
{
|
||||
$sourceFiles = $this->sourceFileRepository->getFiles('', 'source/blog');
|
||||
|
||||
$reversedSourceFiles = array_reverse($sourceFiles);
|
||||
$sourceFiles = $this->sourceFileFilesystemReader
|
||||
->getSourceFiles()->in('/blog/');
|
||||
|
||||
$blogPostRows = [];
|
||||
|
||||
foreach ($reversedSourceFiles as $sourceFile) {
|
||||
foreach ($sourceFiles as $sourceFile) {
|
||||
$blogPostRows[] = [
|
||||
'url' => $sourceFile->getParameter('url'),
|
||||
'slug' => $sourceFile->getParameter('slug'),
|
||||
'title' => $sourceFile->getParameter('title'),
|
||||
'authorName' => (string) $sourceFile->getParameter('authorName'),
|
||||
'authorEmail' => (string) $sourceFile->getParameter('authorEmail'),
|
||||
|
||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
use Doctrine\Website\Repositories\ProjectContributorRepository;
|
||||
|
||||
class Contributors implements DataSource
|
||||
|
||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
|
||||
class DoctrineUsers implements DataSource
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
use Doctrine\Website\Github\GithubProjectContributors;
|
||||
use Doctrine\Website\Repositories\ProjectRepository;
|
||||
use Doctrine\Website\Repositories\TeamMemberRepository;
|
||||
@@ -51,7 +51,13 @@ class ProjectContributors implements DataSource
|
||||
$numDeletions += $week['d'];
|
||||
}
|
||||
|
||||
$teamMember = $this->teamMemberRepository->findOneByGithub($contributor['author']['login']);
|
||||
if (! isset($contributor['author']['login'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$teamMember = $this->teamMemberRepository->findOneByGithub(
|
||||
$contributor['author']['login']
|
||||
);
|
||||
|
||||
$isMaintainer = $teamMember !== null
|
||||
? $teamMember->isProjectMaintainer($project)
|
||||
|
||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
use Doctrine\Website\Projects\ProjectDataReader;
|
||||
use function array_replace;
|
||||
|
||||
|
||||
@@ -5,24 +5,17 @@ declare(strict_types=1);
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
use function file_exists;
|
||||
use function filemtime;
|
||||
use function is_int;
|
||||
use function str_replace;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
use Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRepository;
|
||||
|
||||
class SitemapPages implements DataSource
|
||||
{
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
/** @var SourceFileRepository */
|
||||
private $sourceFileRepository;
|
||||
|
||||
public function __construct(string $sourcePath)
|
||||
public function __construct(SourceFileRepository $sourceFileRepository)
|
||||
{
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->sourceFileRepository = $sourceFileRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,51 +23,15 @@ class SitemapPages implements DataSource
|
||||
*/
|
||||
public function getSourceRows() : array
|
||||
{
|
||||
return array_merge(
|
||||
[
|
||||
[
|
||||
'url' => '/',
|
||||
'date' => new DateTimeImmutable(),
|
||||
],
|
||||
],
|
||||
$this->getSitemapPagesDataFromFiles('projects'),
|
||||
$this->getSitemapPagesDataFromFiles('api')
|
||||
);
|
||||
}
|
||||
$sitemapPages = [];
|
||||
|
||||
/**
|
||||
* @return mixed[][]
|
||||
*/
|
||||
private function getSitemapPagesDataFromFiles(string $path) : array
|
||||
{
|
||||
$path = $this->sourcePath . '/' . $path;
|
||||
|
||||
if (! file_exists($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$it = new RecursiveDirectoryIterator(
|
||||
$path,
|
||||
RecursiveDirectoryIterator::SKIP_DOTS | RecursiveDirectoryIterator::CURRENT_AS_PATHNAME
|
||||
);
|
||||
|
||||
$it = new RecursiveIteratorIterator($it);
|
||||
|
||||
$urls = [];
|
||||
foreach ($it as $file) {
|
||||
$url = str_replace($this->sourcePath, '', $file);
|
||||
|
||||
$timestamp = filemtime($file);
|
||||
assert(is_int($timestamp));
|
||||
|
||||
$date = (new DateTimeImmutable())->setTimestamp($timestamp);
|
||||
|
||||
$urls[] = [
|
||||
'url' => $url,
|
||||
'date' => $date,
|
||||
foreach ($this->sourceFileRepository->getSourceFiles() as $sourceFile) {
|
||||
$sitemapPages[] = [
|
||||
'url' => $sourceFile->getUrl(),
|
||||
'date' => new DateTimeImmutable(),
|
||||
];
|
||||
}
|
||||
|
||||
return $urls;
|
||||
return $sitemapPages;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\DataSources;
|
||||
|
||||
use Doctrine\Website\DataSource\DataSource;
|
||||
use Doctrine\SkeletonMapper\DataSource\DataSource;
|
||||
|
||||
class TeamMembers implements DataSource
|
||||
{
|
||||
|
||||
@@ -17,19 +17,19 @@ class APIBuilder
|
||||
private $processFactory;
|
||||
|
||||
/** @var string */
|
||||
private $projectsPath;
|
||||
private $projectsDir;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
private $sourceDir;
|
||||
|
||||
public function __construct(
|
||||
ProcessFactory $processFactory,
|
||||
string $projectsPath,
|
||||
string $sourcePath
|
||||
string $projectsDir,
|
||||
string $sourceDir
|
||||
) {
|
||||
$this->processFactory = $processFactory;
|
||||
$this->projectsPath = $projectsPath;
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->projectsDir = $projectsDir;
|
||||
$this->sourceDir = $sourceDir;
|
||||
}
|
||||
|
||||
public function buildAPIDocs(
|
||||
@@ -49,9 +49,9 @@ return new Sami\Sami('%s', [
|
||||
]);
|
||||
CONFIG;
|
||||
|
||||
$codeDir = $this->projectsPath . '/' . $project->getRepositoryName() . $project->getCodePath();
|
||||
$buildDir = $this->sourcePath . '/api/' . $project->getSlug() . '/' . $version->getSlug();
|
||||
$cacheDir = $this->projectsPath . '/' . $project->getRepositoryName() . '/cache';
|
||||
$codeDir = $this->projectsDir . '/' . $project->getRepositoryName() . $project->getCodePath();
|
||||
$buildDir = $this->sourceDir . '/api/' . $project->getSlug() . '/' . $version->getSlug();
|
||||
$cacheDir = $this->projectsDir . '/' . $project->getRepositoryName() . '/cache';
|
||||
|
||||
$renderedConfigContent = sprintf(
|
||||
$configContent,
|
||||
@@ -59,12 +59,12 @@ CONFIG;
|
||||
$buildDir,
|
||||
$cacheDir,
|
||||
'doctrine/' . $project->getRepositoryName(),
|
||||
$this->projectsPath . '/' . $project->getRepositoryName(),
|
||||
$this->projectsDir . '/' . $project->getRepositoryName(),
|
||||
$version->getBranchName()
|
||||
);
|
||||
|
||||
$configPath = $this->projectsPath . '/' . $project->getRepositoryName() . '/sami.php';
|
||||
$samiPharPath = $this->sourcePath . '/../sami.phar';
|
||||
$configPath = $this->projectsDir . '/' . $project->getRepositoryName() . '/sami.php';
|
||||
$samiPharPath = $this->sourceDir . '/../sami.phar';
|
||||
|
||||
$this->filePutContents($configPath, $renderedConfigContent);
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@ class RSTBuilder
|
||||
private $filesystem;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
private $sourceDir;
|
||||
|
||||
/** @var string */
|
||||
private $docsPath;
|
||||
private $docsDir;
|
||||
|
||||
public function __construct(
|
||||
RSTFileRepository $rstFileRepository,
|
||||
@@ -39,16 +39,16 @@ class RSTBuilder
|
||||
Builder $builder,
|
||||
RSTPostBuildProcessor $rstPostBuildProcessor,
|
||||
Filesystem $filesystem,
|
||||
string $sourcePath,
|
||||
string $docsPath
|
||||
string $sourceDir,
|
||||
string $docsDir
|
||||
) {
|
||||
$this->rstFileRepository = $rstFileRepository;
|
||||
$this->rstCopier = $rstCopier;
|
||||
$this->builder = $builder;
|
||||
$this->rstPostBuildProcessor = $rstPostBuildProcessor;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->docsPath = $docsPath;
|
||||
$this->sourceDir = $sourceDir;
|
||||
$this->docsDir = $docsDir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ class RSTBuilder
|
||||
*/
|
||||
public function buildRSTDocs(Project $project, ProjectVersion $version, RSTLanguage $language) : array
|
||||
{
|
||||
// copy the docs from the project to a central location in $docsPath
|
||||
// copy the docs from the project to a central location in $docsDir
|
||||
$this->rstCopier->copyRst($project, $version);
|
||||
|
||||
// build the rst and prepare html for ./bin/console build-website
|
||||
@@ -70,7 +70,7 @@ class RSTBuilder
|
||||
|
||||
private function buildRst(Project $project, ProjectVersion $version, RSTLanguage $language) : void
|
||||
{
|
||||
$outputPath = $project->getProjectVersionDocsOutputPath($this->sourcePath, $version, $language->getCode());
|
||||
$outputPath = $project->getProjectVersionDocsOutputPath($this->sourceDir, $version, $language->getCode());
|
||||
|
||||
// clear the files in the output path first
|
||||
$this->filesystem->remove($this->rstFileRepository->findFiles($outputPath));
|
||||
@@ -78,10 +78,10 @@ class RSTBuilder
|
||||
// we have to get a fresh builder due to how the RST parser works
|
||||
$this->builder = $this->builder->recreate();
|
||||
|
||||
// build the docs from the files in $docsPath and write them to $outputPath
|
||||
// which is contained inside the $sourcePath
|
||||
// build the docs from the files in $docsDir and write them to $outputPath
|
||||
// which is contained inside the $sourceDir
|
||||
$this->builder->build(
|
||||
$project->getProjectVersionDocsPath($this->docsPath, $version, $language->getCode()),
|
||||
$project->getProjectVersionDocsPath($this->docsDir, $version, $language->getCode()),
|
||||
$outputPath,
|
||||
false
|
||||
);
|
||||
|
||||
@@ -56,18 +56,18 @@ SIDEBAR;
|
||||
private $filesystem;
|
||||
|
||||
/** @var string */
|
||||
private $docsPath;
|
||||
private $docsDir;
|
||||
|
||||
public function __construct(
|
||||
RSTFileRepository $rstFileRepository,
|
||||
RSTLanguagesDetector $rstLanguagesDetector,
|
||||
Filesystem $filesystem,
|
||||
string $docsPath
|
||||
string $docsDir
|
||||
) {
|
||||
$this->rstFileRepository = $rstFileRepository;
|
||||
$this->rstLanguagesDetector = $rstLanguagesDetector;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->docsPath = $docsPath;
|
||||
$this->docsDir = $docsDir;
|
||||
}
|
||||
|
||||
public function copyRst(Project $project, ProjectVersion $version) : void
|
||||
@@ -75,7 +75,7 @@ SIDEBAR;
|
||||
$languages = $this->rstLanguagesDetector->detectLanguages($project, $version);
|
||||
|
||||
foreach ($languages as $language) {
|
||||
$outputPath = $project->getProjectVersionDocsPath($this->docsPath, $version, $language->getCode());
|
||||
$outputPath = $project->getProjectVersionDocsPath($this->docsDir, $version, $language->getCode());
|
||||
|
||||
// clear existing files before copying the rst over
|
||||
$this->filesystem->remove($this->rstFileRepository->findFiles($outputPath));
|
||||
@@ -131,7 +131,7 @@ SIDEBAR;
|
||||
|
||||
// append the source file name to the content so we can parse it back out
|
||||
// for use in the build process
|
||||
return $content . sprintf('{{ SOURCE_FILE:%s }}', $sourceFile);
|
||||
return $content . sprintf('{{ DOCS_SOURCE_PATH:%s }}', $sourceFile);
|
||||
}
|
||||
|
||||
private function fixRSTSyntax(Project $project, string $content) : string
|
||||
@@ -172,11 +172,11 @@ SIDEBAR;
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function getSidebarRST(string $docsPath) : string
|
||||
private function getSidebarRST(string $docsDir) : string
|
||||
{
|
||||
// check if we have an explicit sidebar file to use
|
||||
// otherwise just use the default autogenerated sidebar
|
||||
$sidebarPath = $docsPath . '/sidebar.rst';
|
||||
$sidebarPath = $docsDir . '/sidebar.rst';
|
||||
|
||||
return file_exists($sidebarPath)
|
||||
? $this->rstFileRepository->getFileContents($sidebarPath)
|
||||
|
||||
@@ -21,11 +21,11 @@ class RSTLanguagesDetector
|
||||
public const ENGLISH_LANGUAGE_CODE = 'en';
|
||||
|
||||
/** @var string */
|
||||
private $projectsPath;
|
||||
private $projectsDir;
|
||||
|
||||
public function __construct(string $projectsPath)
|
||||
public function __construct(string $projectsDir)
|
||||
{
|
||||
$this->projectsPath = $projectsPath;
|
||||
$this->projectsDir = $projectsDir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,11 +35,11 @@ class RSTLanguagesDetector
|
||||
{
|
||||
$finder = new Finder();
|
||||
|
||||
$docsPath = $project->getAbsoluteDocsPath($this->projectsPath);
|
||||
$docsDir = $project->getAbsoluteDocsPath($this->projectsDir);
|
||||
|
||||
$finder
|
||||
->directories()
|
||||
->in($docsPath);
|
||||
->in($docsDir);
|
||||
|
||||
$files = array_values(array_map(static function (SplFileInfo $file) {
|
||||
return $file->getRealPath();
|
||||
@@ -59,7 +59,7 @@ class RSTLanguagesDetector
|
||||
continue;
|
||||
}
|
||||
|
||||
$languagePath = $project->getAbsoluteDocsPath($this->projectsPath) . '/' . $languageCode;
|
||||
$languagePath = $project->getAbsoluteDocsPath($this->projectsDir) . '/' . $languageCode;
|
||||
|
||||
$languages[] = new RSTLanguage(
|
||||
$languageCode,
|
||||
@@ -71,7 +71,7 @@ class RSTLanguagesDetector
|
||||
}
|
||||
|
||||
return [
|
||||
new RSTLanguage(self::ENGLISH_LANGUAGE_CODE, $project->getAbsoluteDocsPath($this->projectsPath)),
|
||||
new RSTLanguage(self::ENGLISH_LANGUAGE_CODE, $project->getAbsoluteDocsPath($this->projectsDir)),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,18 +17,9 @@ class RSTPostBuildProcessor
|
||||
{
|
||||
public const PARAMETERS_TEMPLATE = <<<TEMPLATE
|
||||
---
|
||||
layout: "documentation"
|
||||
indexed: true
|
||||
title: "%s"
|
||||
menuSlug: "projects"
|
||||
docsSlug: "%s"
|
||||
docsPage: true
|
||||
docsIndex: %s
|
||||
docsVersion: "%s"
|
||||
sourceFile: "%s"
|
||||
lanuage: "%s"
|
||||
permalink: "none"
|
||||
controller: ['Doctrine\Website\Controllers\DocumentationController', 'view']
|
||||
docsSourcePath: "%s"
|
||||
---
|
||||
%s
|
||||
TEMPLATE;
|
||||
@@ -40,22 +31,22 @@ TEMPLATE;
|
||||
private $filesystem;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
private $sourceDir;
|
||||
|
||||
public function __construct(
|
||||
RSTFileRepository $rstFileRepository,
|
||||
Filesystem $filesystem,
|
||||
string $sourcePath
|
||||
string $sourceDir
|
||||
) {
|
||||
$this->rstFileRepository = $rstFileRepository;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->sourceDir = $sourceDir;
|
||||
}
|
||||
|
||||
public function postRstBuild(Project $project, ProjectVersion $version, RSTLanguage $language) : void
|
||||
{
|
||||
$projectVersionDocsOutputPath = $project->getProjectVersionDocsOutputPath(
|
||||
$this->sourcePath,
|
||||
$this->sourceDir,
|
||||
$version,
|
||||
$language->getCode()
|
||||
);
|
||||
@@ -110,11 +101,11 @@ TEMPLATE;
|
||||
string $contents
|
||||
) : string {
|
||||
// parse out the source file that generated this file
|
||||
preg_match('/<p>{{ SOURCE_FILE:(.*) }}<\/p>/', $contents, $match);
|
||||
preg_match('/<p>{{ DOCS_SOURCE_PATH:(.*) }}<\/p>/', $contents, $match);
|
||||
|
||||
$sourceFile = $match[1];
|
||||
$docsSourcePath = $match[1];
|
||||
|
||||
// get rid of the special SOURCE_FILE: syntax in the contents
|
||||
// get rid of the special DOCS_SOURCE_PATH: syntax in the contents
|
||||
$contents = str_replace($match[0], '', $contents);
|
||||
|
||||
$title = $this->extractTitle($contents);
|
||||
@@ -124,11 +115,8 @@ TEMPLATE;
|
||||
return sprintf(
|
||||
self::PARAMETERS_TEMPLATE,
|
||||
$title,
|
||||
$project->getDocsSlug(),
|
||||
strpos($file, 'index.html') !== false ? 'true' : 'false',
|
||||
$version->getSlug(),
|
||||
$sourceFile,
|
||||
$language->getCode(),
|
||||
$docsSourcePath,
|
||||
$contents
|
||||
);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ class SearchIndexer
|
||||
foreach ($nodes as $node) {
|
||||
$value = (string) $node->getValue();
|
||||
|
||||
if (strpos($value, '{{ SOURCE_FILE') !== false) {
|
||||
if (strpos($value, '{{ DOCS_SOURCE_PATH') !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ class BlogPost implements HydratableInterface, LoadMetadataInterface
|
||||
/** @var string */
|
||||
private $url;
|
||||
|
||||
/** @var string */
|
||||
private $slug;
|
||||
|
||||
/** @var string */
|
||||
private $title;
|
||||
|
||||
@@ -32,6 +35,7 @@ class BlogPost implements HydratableInterface, LoadMetadataInterface
|
||||
|
||||
public function __construct(
|
||||
string $url,
|
||||
string $slug,
|
||||
string $title,
|
||||
string $authorName,
|
||||
string $authorEmail,
|
||||
@@ -39,6 +43,7 @@ class BlogPost implements HydratableInterface, LoadMetadataInterface
|
||||
DateTimeImmutable $date
|
||||
) {
|
||||
$this->url = $url;
|
||||
$this->slug = $slug;
|
||||
$this->title = $title;
|
||||
$this->authorName = $authorName;
|
||||
$this->authorEmail = $authorEmail;
|
||||
@@ -48,7 +53,7 @@ class BlogPost implements HydratableInterface, LoadMetadataInterface
|
||||
|
||||
public static function loadMetadata(ClassMetadataInterface $metadata) : void
|
||||
{
|
||||
$metadata->setIdentifier(['url']);
|
||||
$metadata->setIdentifier(['slug']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +62,7 @@ class BlogPost implements HydratableInterface, LoadMetadataInterface
|
||||
public function hydrate(array $project, ObjectManagerInterface $objectManager) : void
|
||||
{
|
||||
$this->url = (string) $project['url'] ?? '';
|
||||
$this->slug = (string) $project['slug'] ?? '';
|
||||
$this->title = (string) $project['title'] ?? '';
|
||||
$this->authorName = (string) $project['authorName'] ?? '';
|
||||
$this->authorEmail = (string) $project['authorEmail'] ?? '';
|
||||
@@ -69,6 +75,11 @@ class BlogPost implements HydratableInterface, LoadMetadataInterface
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function getSlug() : string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function getTitle() : string
|
||||
{
|
||||
return $this->title;
|
||||
|
||||
@@ -273,19 +273,19 @@ class Project implements HydratableInterface, LoadMetadataInterface
|
||||
})[0] ?? ($this->versions[0] ?? null);
|
||||
}
|
||||
|
||||
public function getProjectDocsRepositoryPath(string $projectsPath) : string
|
||||
public function getProjectDocsRepositoryPath(string $projectsDir) : string
|
||||
{
|
||||
return $projectsPath . '/' . $this->getDocsRepositoryName();
|
||||
return $projectsDir . '/' . $this->getDocsRepositoryName();
|
||||
}
|
||||
|
||||
public function getProjectRepositoryPath(string $projectsPath) : string
|
||||
public function getProjectRepositoryPath(string $projectsDir) : string
|
||||
{
|
||||
return $projectsPath . '/' . $this->getRepositoryName();
|
||||
return $projectsDir . '/' . $this->getRepositoryName();
|
||||
}
|
||||
|
||||
public function getAbsoluteDocsPath(string $projectsPath) : string
|
||||
public function getAbsoluteDocsPath(string $projectsDir) : string
|
||||
{
|
||||
return $this->getProjectDocsRepositoryPath($projectsPath) . $this->getDocsPath();
|
||||
return $this->getProjectDocsRepositoryPath($projectsDir) . $this->getDocsPath();
|
||||
}
|
||||
|
||||
public function getProjectVersionDocsPath(string $docsPath, ProjectVersion $version, string $language) : string
|
||||
|
||||
@@ -25,7 +25,7 @@ class ProjectDataReader
|
||||
private const COMPOSER_JSON_FILE_NAME = 'composer.json';
|
||||
|
||||
/** @var string */
|
||||
private $projectsPath;
|
||||
private $projectsDir;
|
||||
|
||||
/** @var mixed[] */
|
||||
private $projectsData;
|
||||
@@ -38,11 +38,11 @@ class ProjectDataReader
|
||||
* @param mixed[] $projectIntegrationTypes
|
||||
*/
|
||||
public function __construct(
|
||||
string $projectsPath,
|
||||
string $projectsDir,
|
||||
array $projectsData,
|
||||
array $projectIntegrationTypes
|
||||
) {
|
||||
$this->projectsPath = $projectsPath;
|
||||
$this->projectsDir = $projectsDir;
|
||||
$this->projectsData = $projectsData;
|
||||
$this->projectIntegrationTypes = $projectIntegrationTypes;
|
||||
}
|
||||
@@ -142,7 +142,7 @@ class ProjectDataReader
|
||||
private function detectPath(string $repositoryName, array $pathsToCheck, ?string $default) : ?string
|
||||
{
|
||||
foreach ($pathsToCheck as $path) {
|
||||
$check = $this->projectsPath . '/' . $repositoryName . $path;
|
||||
$check = $this->projectsDir . '/' . $repositoryName . $path;
|
||||
|
||||
if (is_dir($check)) {
|
||||
return $path;
|
||||
@@ -181,7 +181,7 @@ class ProjectDataReader
|
||||
*/
|
||||
private function readJsonFile(string $repositoryName, string $fileName) : array
|
||||
{
|
||||
$filePath = $this->projectsPath . '/' . $repositoryName . '/' . $fileName;
|
||||
$filePath = $this->projectsDir . '/' . $repositoryName . '/' . $fileName;
|
||||
|
||||
if (! file_exists($filePath)) {
|
||||
return [];
|
||||
|
||||
@@ -16,22 +16,22 @@ class ProjectGitSyncer
|
||||
private $processFactory;
|
||||
|
||||
/** @var string */
|
||||
private $projectsPath;
|
||||
private $projectsDir;
|
||||
|
||||
public function __construct(ProcessFactory $processFactory, string $projectsPath)
|
||||
public function __construct(ProcessFactory $processFactory, string $projectsDir)
|
||||
{
|
||||
$this->processFactory = $processFactory;
|
||||
$this->projectsPath = $projectsPath;
|
||||
$this->projectsDir = $projectsDir;
|
||||
}
|
||||
|
||||
public function isRepositoryInitialized(string $repositoryName) : bool
|
||||
{
|
||||
return is_dir($this->projectsPath . '/' . $repositoryName);
|
||||
return is_dir($this->projectsDir . '/' . $repositoryName);
|
||||
}
|
||||
|
||||
public function initRepository(string $repositoryName) : void
|
||||
{
|
||||
$repositoryPath = $this->projectsPath . '/' . $repositoryName;
|
||||
$repositoryPath = $this->projectsDir . '/' . $repositoryName;
|
||||
|
||||
if (is_dir($repositoryPath)) {
|
||||
return;
|
||||
@@ -51,13 +51,13 @@ class ProjectGitSyncer
|
||||
// handle when docs are in a different repository then the code
|
||||
if ($project->getDocsRepositoryName() !== $project->getRepositoryName()) {
|
||||
$this->syncRepository(
|
||||
$project->getProjectRepositoryPath($this->projectsPath)
|
||||
$project->getProjectRepositoryPath($this->projectsDir)
|
||||
);
|
||||
}
|
||||
|
||||
// sync docs repository
|
||||
$this->syncRepository(
|
||||
$project->getProjectDocsRepositoryPath($this->projectsPath)
|
||||
$project->getProjectDocsRepositoryPath($this->projectsDir)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,10 +74,10 @@ class ProjectGitSyncer
|
||||
private function checkoutBranch(Project $project, string $branchName) : void
|
||||
{
|
||||
if ($project->getDocsRepositoryName() !== $project->getRepositoryName()) {
|
||||
$this->doCheckoutBranch($project->getProjectRepositoryPath($this->projectsPath), $branchName);
|
||||
$this->doCheckoutBranch($project->getProjectRepositoryPath($this->projectsDir), $branchName);
|
||||
}
|
||||
|
||||
$this->doCheckoutBranch($project->getProjectDocsRepositoryPath($this->projectsPath), $branchName);
|
||||
$this->doCheckoutBranch($project->getProjectDocsRepositoryPath($this->projectsDir), $branchName);
|
||||
}
|
||||
|
||||
private function doCheckoutBranch(string $directory, string $branchName) : void
|
||||
|
||||
@@ -5,11 +5,13 @@ declare(strict_types=1);
|
||||
namespace Doctrine\Website\RST;
|
||||
|
||||
use Doctrine\RST\Builder;
|
||||
use Doctrine\RST\Configuration;
|
||||
use Doctrine\RST\Directive;
|
||||
use Doctrine\RST\Document;
|
||||
use Doctrine\RST\Factory;
|
||||
use Doctrine\RST\Environment as BaseEnvironment;
|
||||
use Doctrine\RST\HTML\Kernel as HtmlKernel;
|
||||
use Doctrine\RST\Kernel as BaseKernel;
|
||||
use Doctrine\RST\NodeFactory;
|
||||
use Doctrine\RST\Reference;
|
||||
use function array_merge;
|
||||
|
||||
@@ -19,7 +21,7 @@ class Kernel extends BaseKernel
|
||||
private $baseKernel;
|
||||
|
||||
/** @var Directive[] */
|
||||
private $directives;
|
||||
protected $directives;
|
||||
|
||||
/**
|
||||
* @param Directive[] $directives
|
||||
@@ -29,7 +31,7 @@ class Kernel extends BaseKernel
|
||||
$this->baseKernel = $baseKernel;
|
||||
$this->directives = $directives;
|
||||
|
||||
parent::__construct($directives);
|
||||
parent::__construct(null, $directives);
|
||||
}
|
||||
|
||||
public function getName() : string
|
||||
@@ -40,9 +42,14 @@ class Kernel extends BaseKernel
|
||||
/**
|
||||
* @return Directive[]
|
||||
*/
|
||||
public function getDirectives() : array
|
||||
public function createDirectives() : array
|
||||
{
|
||||
return array_merge($this->baseKernel->getDirectives(), $this->directives);
|
||||
return array_merge($this->baseKernel->createDirectives(), $this->directives);
|
||||
}
|
||||
|
||||
public function createEnvironment(?Configuration $configuration = null) : BaseEnvironment
|
||||
{
|
||||
return $this->baseKernel->createEnvironment($configuration);
|
||||
}
|
||||
|
||||
public function getFileExtension() : string
|
||||
@@ -50,11 +57,6 @@ class Kernel extends BaseKernel
|
||||
return $this->baseKernel->getFileExtension();
|
||||
}
|
||||
|
||||
public function getFactory() : Factory
|
||||
{
|
||||
return $this->baseKernel->getFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Reference[]
|
||||
*/
|
||||
@@ -72,4 +74,9 @@ class Kernel extends BaseKernel
|
||||
{
|
||||
$this->baseKernel->initBuilder($builder);
|
||||
}
|
||||
|
||||
protected function createNodeFactory() : NodeFactory
|
||||
{
|
||||
return $this->baseKernel->createNodeFactory();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ use Doctrine\Website\Model\Contributor;
|
||||
|
||||
class ContributorRepository extends BasicObjectRepository
|
||||
{
|
||||
public function findOneByGithub(string $github) : Contributor
|
||||
{
|
||||
return $this->findOneBy(['github' => $github]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Contributor[]
|
||||
*/
|
||||
|
||||
37
lib/Requests/ContributorRequests.php
Normal file
37
lib/Requests/ContributorRequests.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Requests;
|
||||
|
||||
use Doctrine\StaticWebsiteGenerator\Request\ArrayRequestCollection;
|
||||
use Doctrine\StaticWebsiteGenerator\Request\RequestCollection;
|
||||
use Doctrine\Website\Model\Contributor;
|
||||
use Doctrine\Website\Repositories\ContributorRepository;
|
||||
|
||||
class ContributorRequests
|
||||
{
|
||||
/** @var ContributorRepository */
|
||||
private $contributorRepository;
|
||||
|
||||
public function __construct(ContributorRepository $contributorRepository)
|
||||
{
|
||||
$this->contributorRepository = $contributorRepository;
|
||||
}
|
||||
|
||||
public function getContributors() : RequestCollection
|
||||
{
|
||||
/** @var Contributor[] $contributors */
|
||||
$contributors = $this->contributorRepository->findAll();
|
||||
|
||||
$requests = [];
|
||||
|
||||
foreach ($contributors as $contributor) {
|
||||
$requests[] = [
|
||||
'github' => $contributor->getGithub(),
|
||||
];
|
||||
}
|
||||
|
||||
return new ArrayRequestCollection($requests);
|
||||
}
|
||||
}
|
||||
88
lib/Site.php
88
lib/Site.php
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website;
|
||||
|
||||
class Site
|
||||
{
|
||||
/** @var string */
|
||||
private $title;
|
||||
|
||||
/** @var string */
|
||||
private $subtitle;
|
||||
|
||||
/** @var string */
|
||||
private $url;
|
||||
|
||||
/** @var string[] */
|
||||
private $keywords;
|
||||
|
||||
/** @var string */
|
||||
private $description;
|
||||
|
||||
/** @var string */
|
||||
private $env;
|
||||
|
||||
/** @var string */
|
||||
private $googleAnalyticsTrackingId;
|
||||
|
||||
/**
|
||||
* @param string[] $keywords
|
||||
*/
|
||||
public function __construct(
|
||||
string $title,
|
||||
string $subtitle,
|
||||
string $url,
|
||||
array $keywords,
|
||||
string $description,
|
||||
string $env,
|
||||
string $googleAnalyticsTrackingId
|
||||
) {
|
||||
$this->title = $title;
|
||||
$this->subtitle = $subtitle;
|
||||
$this->url = $url;
|
||||
$this->keywords = $keywords;
|
||||
$this->description = $description;
|
||||
$this->env = $env;
|
||||
$this->googleAnalyticsTrackingId = $googleAnalyticsTrackingId;
|
||||
}
|
||||
|
||||
public function getTitle() : string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getSubtitle() : string
|
||||
{
|
||||
return $this->subtitle;
|
||||
}
|
||||
|
||||
public function getUrl() : string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getKeywords() : array
|
||||
{
|
||||
return $this->keywords;
|
||||
}
|
||||
|
||||
public function getDescription() : string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function getEnv() : string
|
||||
{
|
||||
return $this->env;
|
||||
}
|
||||
|
||||
public function googleAnalyticsTrackingId() : string
|
||||
{
|
||||
return $this->googleAnalyticsTrackingId;
|
||||
}
|
||||
}
|
||||
@@ -26,17 +26,17 @@ class MainExtension extends Twig_Extension
|
||||
private $assetIntegrityGenerator;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
private $sourceDir;
|
||||
|
||||
/** @var string */
|
||||
private $webpackBuildPath;
|
||||
private $webpackBuildDir;
|
||||
|
||||
public function __construct(Parsedown $parsedown, AssetIntegrityGenerator $assetIntegrityGenerator, string $sourcePath, string $webpackBuildPath)
|
||||
public function __construct(Parsedown $parsedown, AssetIntegrityGenerator $assetIntegrityGenerator, string $sourceDir, string $webpackBuildDir)
|
||||
{
|
||||
$this->parsedown = $parsedown;
|
||||
$this->assetIntegrityGenerator = $assetIntegrityGenerator;
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->webpackBuildPath = $webpackBuildPath;
|
||||
$this->sourceDir = $sourceDir;
|
||||
$this->webpackBuildDir = $webpackBuildDir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,12 +82,12 @@ class MainExtension extends Twig_Extension
|
||||
|
||||
public function getAssetUrl(string $path, string $siteUrl, string $rootPath = null) : string
|
||||
{
|
||||
return $siteUrl . $path . '?' . $this->getAssetCacheBuster($path, $rootPath ?? $this->sourcePath);
|
||||
return $siteUrl . $path . '?' . $this->getAssetCacheBuster($path, $rootPath ?? $this->sourceDir);
|
||||
}
|
||||
|
||||
public function getWebpackAssetUrl(string $path, string $siteUrl) : string
|
||||
{
|
||||
return $this->getAssetUrl($path, $siteUrl, $this->webpackBuildPath);
|
||||
return $this->getAssetUrl($path, $siteUrl, $this->webpackBuildDir);
|
||||
}
|
||||
|
||||
private function getAssetCacheBuster(string $path, string $rootPath) : string
|
||||
|
||||
@@ -19,12 +19,12 @@ class ProjectExtension extends Twig_Extension
|
||||
private $projectRepository;
|
||||
|
||||
/** @var string */
|
||||
private $sourcePath;
|
||||
private $sourceDir;
|
||||
|
||||
public function __construct(ProjectRepository $projectRepository, string $sourcePath)
|
||||
public function __construct(ProjectRepository $projectRepository, string $sourceDir)
|
||||
{
|
||||
$this->projectRepository = $projectRepository;
|
||||
$this->sourcePath = $sourcePath;
|
||||
$this->sourceDir = $sourceDir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ class ProjectExtension extends Twig_Extension
|
||||
$otherVersionUrl = str_replace($currentVersion, $projectVersion->getSlug(), $url);
|
||||
}
|
||||
|
||||
$otherVersionFile = $this->sourcePath . $otherVersionUrl;
|
||||
$otherVersionFile = $this->sourceDir . $otherVersionUrl;
|
||||
|
||||
if (! $this->fileExists($otherVersionFile)) {
|
||||
return null;
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website\Twig;
|
||||
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use Twig\Loader\ChainLoader;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
|
||||
class TwigRenderer
|
||||
{
|
||||
/** @var MainExtension */
|
||||
private $mainExtension;
|
||||
|
||||
/** @var ProjectExtension */
|
||||
private $projectExtension;
|
||||
|
||||
/** @var string */
|
||||
private $templatesPath;
|
||||
|
||||
public function __construct(
|
||||
MainExtension $mainExtension,
|
||||
ProjectExtension $projectExtension,
|
||||
string $templatesPath
|
||||
) {
|
||||
$this->mainExtension = $mainExtension;
|
||||
$this->projectExtension = $projectExtension;
|
||||
$this->templatesPath = $templatesPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $parameters
|
||||
*/
|
||||
public function render(string $twig, array $parameters) : string
|
||||
{
|
||||
$name = $parameters['page']['url'];
|
||||
|
||||
$loader = new ArrayLoader([$name => $twig]);
|
||||
|
||||
$chainLoader = new ChainLoader([
|
||||
$loader,
|
||||
new FilesystemLoader($this->templatesPath),
|
||||
]);
|
||||
|
||||
$twig = new Environment($chainLoader, ['strict_variables' => true]);
|
||||
$twig->addExtension($this->mainExtension);
|
||||
$twig->addExtension($this->projectExtension);
|
||||
|
||||
return $twig->render($name, $parameters);
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Website;
|
||||
|
||||
use Doctrine\Website\Builder\SourceFileBuilder;
|
||||
use Doctrine\Website\Builder\SourceFileRepository;
|
||||
use Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRepository;
|
||||
use Doctrine\StaticWebsiteGenerator\SourceFile\SourceFilesBuilder;
|
||||
use Doctrine\Website\Model\Project;
|
||||
use Doctrine\Website\Model\ProjectVersion;
|
||||
use Doctrine\Website\Repositories\ProjectRepository;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Throwable;
|
||||
use function chdir;
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
@@ -47,26 +46,26 @@ class WebsiteBuilder
|
||||
/** @var SourceFileRepository */
|
||||
private $sourceFileRepository;
|
||||
|
||||
/** @var SourceFileBuilder */
|
||||
private $sourceFileBuilder;
|
||||
/** @var SourceFilesBuilder */
|
||||
private $sourceFilesBuilder;
|
||||
|
||||
/** @var string */
|
||||
private $webpackBuildPath;
|
||||
private $webpackBuildDir;
|
||||
|
||||
public function __construct(
|
||||
ProcessFactory $processFactory,
|
||||
ProjectRepository $projectRepository,
|
||||
Filesystem $filesystem,
|
||||
SourceFileRepository $sourceFileRepository,
|
||||
SourceFileBuilder $sourceFileBuilder,
|
||||
string $webpackBuildPath
|
||||
SourceFilesBuilder $sourceFilesBuilder,
|
||||
string $webpackBuildDir
|
||||
) {
|
||||
$this->processFactory = $processFactory;
|
||||
$this->projectRepository = $projectRepository;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->sourceFileRepository = $sourceFileRepository;
|
||||
$this->sourceFileBuilder = $sourceFileBuilder;
|
||||
$this->webpackBuildPath = $webpackBuildPath;
|
||||
$this->processFactory = $processFactory;
|
||||
$this->projectRepository = $projectRepository;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->sourceFileRepository = $sourceFileRepository;
|
||||
$this->sourceFilesBuilder = $sourceFilesBuilder;
|
||||
$this->webpackBuildDir = $webpackBuildDir;
|
||||
}
|
||||
|
||||
public function build(
|
||||
@@ -124,35 +123,27 @@ class WebsiteBuilder
|
||||
// Move webpack assets into build directory
|
||||
$this->buildWebpackAssets($buildDir, $isPublishableEnv);
|
||||
|
||||
foreach ($this->sourceFileRepository->getFiles($buildDir) as $file) {
|
||||
try {
|
||||
$this->sourceFileBuilder->buildFile($file, $buildDir);
|
||||
} catch (Throwable $e) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Failed building file "%s" with error "%s',
|
||||
$file->getWritePath(),
|
||||
$e->getMessage() . "\n\n" . $e->getTraceAsString()
|
||||
));
|
||||
}
|
||||
}
|
||||
$this->sourceFilesBuilder->buildSourceFiles(
|
||||
$this->sourceFileRepository->getSourceFiles($buildDir)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildWebpackAssets(string $buildDir, bool $isPublishableEnv) : void
|
||||
{
|
||||
$this->filesystem->remove(glob($this->webpackBuildPath . '/*'));
|
||||
$this->filesystem->remove(glob($this->webpackBuildDir . '/*'));
|
||||
$this->processFactory->run(sprintf('cd %s && npm run %s',
|
||||
$buildDir, $isPublishableEnv ? 'build' : 'dev'));
|
||||
|
||||
// Copy built assets if this is a publishable build
|
||||
if ($isPublishableEnv) {
|
||||
$this->filesystem->mirror($this->webpackBuildPath, $buildDir);
|
||||
$this->filesystem->mirror($this->webpackBuildDir, $buildDir);
|
||||
return;
|
||||
}
|
||||
|
||||
// Symlink files to allow files to auto update using webpack --watch
|
||||
$this->filesystem->mkdir($buildDir);
|
||||
$this->filesystem->symlink($this->webpackBuildPath . '/css', $buildDir . '/css', true);
|
||||
$this->filesystem->symlink($this->webpackBuildPath . '/js', $buildDir . '/js', true);
|
||||
$this->filesystem->symlink($this->webpackBuildDir . '/css', $buildDir . '/css', true);
|
||||
$this->filesystem->symlink($this->webpackBuildDir . '/js', $buildDir . '/js', true);
|
||||
}
|
||||
|
||||
private function createProjectVersionAliases(string $buildDir) : void
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
---
|
||||
layout: default
|
||||
title: Blog Archive
|
||||
menuSlug: blog
|
||||
permalink: /blog/archive.html
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'archive']
|
||||
---
|
||||
|
||||
<h1>Blog Archive</h1>
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
---
|
||||
permalink: /atom.xml
|
||||
controller: ['Doctrine\Website\Controllers\AtomController', 'index']
|
||||
---
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title><![CDATA[{{ site.title }}]]></title>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
---
|
||||
layout: default
|
||||
title: Blog
|
||||
menuSlug: blog
|
||||
permalink: /blog/index.html
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'index']
|
||||
---
|
||||
|
||||
{% for blogPost in blogPosts %}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "New Website"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "New Coverage Report"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Beta 2"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Beta 2 Released"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "URL Changes"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "New Design"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Project Status"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Cleaning up the mess"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: guilhermeblanco
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "A few updates for 2008"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Using Doctrine with CodeIgniter"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine all grown up"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine 0.9.1 / 0.10.1 Released"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine ORM Sandbox"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.10.2 Released"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "My First Project Doctrine Tutorial"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine Cheat Sheet"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "4,000th svn commit/revision"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.10.3 Released"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.10.4 Released - 46 Closed Tickets"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Using Doctrine with Zend Framework"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "APRIL FOOLS! Doctrine goes PECL"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine frequently asked questions"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.11.0 Release Candidate 1"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.11.0 Release Candidate 2"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Wow! 1000 tickets"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Website upgraded to symfony 1.1 and Doctrine 0.11"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Road to Doctrine 1.0"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.11.0-RC3 Released"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "One more 0.11 Release Candidate"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Php.net style API documentation lookups"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Getting started with Doctrine and symfony 1.1"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine in your language"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Introducing the Doctrine Cookbook"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "0.11.0 Stable Released"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: [release]
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "1000th Ticket Closed"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Introducing the Doctrine Forum"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine 1.0 and symfony 1.2"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine 0.11.1 and 1.0"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Doctrine gets its first employee"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
---
|
||||
title: "Plug and Play Schema Information With Templates"
|
||||
menuSlug: blog
|
||||
layout: blog-post
|
||||
controller: ['Doctrine\Website\Controllers\BlogController', 'view']
|
||||
authorName: jwage
|
||||
authorEmail:
|
||||
categories: []
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user