Pimcore(Symfony+Twig)開発ティップス

Twig文字制限

Twig length

Twig slice

{{ myentity.text[:50] ~ (myentity.text|length > 50 ? '…') }}

補足:省略記号 ellipsis character ‘…’
スリードット ... ではなく1つのキャラクターとして を表示

注)Linux:Ubuntuの場合(MAC,Windowsではキーが異なります)

  1. Ctrl + Shift + ‘u’ 押下
  2. キーリリース
  3. 続けて"2026"を入力,
  4. エンターキー押下

Twig dump

テンプレート内の変数確認

<pre>
    {{ dump(item) }}
</pre>
Pimcore\Model\DataObject\Fieldcollection\Data\NewsText {#2378 ▼
  #type: "NewsText"
  #localizedfields: Pimcore\Model\DataObject\Localizedfield {#2384 ▶}
  #index: 0
  #fieldname: "content"
  #object: null
  #objectId: 1158
  #dao: null
  #_fulldump: false
  #loadedLazyKeys: []
  #o_dirtyFields: null
  type: "NewsText"
  localizedfields: Pimcore\Model\DataObject\Localizedfield {#2384 ▶}
  index: 0
  fieldname: "content"
  object: null
  objectId: 1158
  _fulldump: false
  loadedLazyKeys: []
  o_dirtyFields: null
}

Twig striptags

htmlテキストファイルから <p>,<br> 等のタグを除外

EX) テキストソース頭から200文字を抽出後タグを削除。文字数が200文字を超えていたら '…' による省略記号追加。

{% if news.content %}
    {% for item in news.content.items %}
        {% if item.type == "NewsText" %}
            {{ item.text[:200] | striptags ~ (item.text|length > 200 ? '…') }}
        {% endif %}   
    {% endfor %}
{% endif %}

'~'によるフィルタリングを施すと特殊文字(例:&#039;)がそのまま出力されてしまうため以下の記述に変更。

{% if news.content %}
    {% for item in news.content.items %}
        {% if item.type == "NewsText" %}
            {{ item.text[:200] | striptags | raw }} .....
        {% endif %}   
    {% endfor %}
{% endif %}

Twig Replace

上記のタグ削除に non-breaking space &nbsp;" "への置換え追加
non-breaking spaceは、単位と数値の間の改行禁止のスペース

  • § 10
  • 10 km/h
  • 10 PM
{% if news.content %}
    {% for item in news.content.items %}
        {% if item.type == "NewsText" %}
            {{ item.text[:200] | striptags | replace({'&nbsp;': " "}) ~ (item.text|length > 200 ? '…') }}
        {% endif %}   
    {% endfor %}
{% endif %}

Twig Operators

条件設定

  • ?:: The ternary operator:
{{ foo ? 'yes' : 'no' }}
{{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}

Twig Logic

論理条件定義

  • and: Returns true if the left and the right operands are both true.
  • or: Returns true if the left or the right operand is true.
  • not: Negates a statement.
  • (expr): Groups an expression.

Twig Date

日付表示

Twig date_modify

{{ post.published_at|date_modify("+1 day")|date("m/d/Y") }}

Twig path

{{ path(route_name, route_parameters = [], relative = false) }}

name

type: string

parameters (optional)

type: array default: []

relative (optional)

type: boolean default: false

Returns the relative URL (without the scheme and host) for the given route. If relative is enabled, it’ll create a path relative to the current path.

Other Operaters

  • |: Applies a filter.

  • ~ : Converts all operands into strings and concatenates them.

  • ., []: Gets an attribute of a variable.

  • ?:: The ternary operator:

  • ?? : The null-coalescing operator:

Link Generatorで使用するTextクラスの漢字のローマ字変換について

以下問題と同様、リンクURLに日本語タイトルを挿入する際、ひらがなカナの読み方は正しくローマ字に変換されるが、漢字についてはピンインの読みとなってしまう。

漢字の日本語読みは複数のため、Latin規格に取り込まれていない模様。

Link Generator(Blog)

Website/LinkGenerator/BlogLinkGenerator.php

'blogtitle' => Text::toUrl($object->getTitle() ? $object->getTitle() : 'blog'),

Textクラス

Website/Tool/Text.php

public static function toUrl($text)
    {
        // to ASCII
        $text = trim(transliterator_transliterate('Any-Latin; Latin-ASCII; [^\u001F-\u007f] remove', $text));

        $search = ['?', '\'', '"', '/', '-', '+', '.', ',', ';', '(', ')', ' ', '&', 'ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß', 'É', 'é', 'È', 'è', 'Ê', 'ê', 'E', 'e', 'Ë', 'ë',
                         'À', 'à', 'Á', 'á', 'Å', 'å', 'a', 'Â', 'â', 'Ã', 'ã', 'ª', 'Æ', 'æ', 'C', 'c', 'Ç', 'ç', 'C', 'c', 'Í', 'í', 'Ì', 'ì', 'Î', 'î', 'Ï', 'ï',
                         'Ó', 'ó', 'Ò', 'ò', 'Ô', 'ô', 'º', 'Õ', 'õ', 'Œ', 'O', 'o', 'Ø', 'ø', 'Ú', 'ú', 'Ù', 'ù', 'Û', 'û', 'U', 'u', 'U', 'u', 'Š', 'š', 'S', 's',
                         'Ž', 'ž', 'Z', 'z', 'Z', 'z', 'L', 'l', 'N', 'n', 'Ñ', 'ñ', '¡', '¿',  'Ÿ', 'ÿ', '_', ':' ];
        $replace = ['', '', '', '', '-', '', '', '-', '-', '', '', '-', '', 'ae', 'oe', 'ue', 'Ae', 'Oe', 'Ue', 'ss', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e',
                         'A', 'a', 'A', 'a', 'A', 'a', 'a', 'A', 'a', 'A', 'a', 'a', 'AE', 'ae', 'C', 'c', 'C', 'c', 'C', 'c', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i',
                         'O', 'o', 'O', 'o', 'O', 'o', 'o', 'O', 'o', 'OE', 'O', 'o', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'S', 's', 'S', 's',
                         'Z', 'z', 'Z', 'z', 'Z', 'z', 'L', 'l', 'N', 'n', 'N', 'n', '', '', 'Y', 'y', '-', '-' ];

        $value = urlencode(str_replace($search, $replace, $text));

        return $value;
    }

PHP Transliterator::transliterate
https://www.php.net/manual/en/transliterator.transliterate.php

Font-Family

system-ui

指定されたプラットフォームの既定のユーザーインターフェイスフォントからグリフを取ります。文字の伝統は世界で様々であるため、この総称は他の総称にきれいに一致しない文字フォントを提供します。

PImcore(Symfony)のデバッグモード

.env ファイルにより、SymfonyによるデバックとPimcoreによるデバックを別々に設定可能です。

Symfonyによるデバックモード

APP_ENV=dev

)Symfonyのデバックモードの場合、サイト下部にデバックメニューが表示されるため、本番環境移行の際にはSymfonyのデバックモードを無効にする必要があります。

APP_ENV=prod

Pimcoreによるデバックモード

PIMCORE_DEV_MODE=true

Logging ログファイル

PimcoreまたはSymfonyにより作成されるログファイルは project/var/log に作成・保存されます。
各ログファイルは7日間アーカイブ保存されますが、Symfonyのデバックモード有効時(APP_ENV=dev)のDEVログファイルは1日のアーカイブ容量が数百MBを浪費するため注意が必要です。

Logging-Pimcore

Symfony Logging

File Permissions

Pimcore

パーミッションと bin フォルダ内スクリプト実行権の付与

$ sudo chown -R YOURUSER:YOURGROUP var public/var
$ sudo chmod ug+x bin/*

Symfony

サイトマップ (Sitemaps)

Pimcore Sitemaps

CAUTION

To use this feature, please enable the PimcoreSeoBundle in your bundle.php file and install it accordingly with the following command:

# bin/console pimcore:bundle:install PimcoreSeoBundle

PrestaSitemap Installation

PrestaSitemap Configuration

vendor/presta フォルダーに以下のパッケージがない場合にインストール

$ composer require presta/sitemap-bundle

config/bundles.php に以下追加

<?php
return [
    //...
    Presta\SitemapBundle\PrestaSitemapBundle::class => ['all' => true],
];

上記パッケージの設定ファイルをインポート
config/routes/presta_sitemap.yaml

presta_sitemap:
    resource: "@PrestaSitemapBundle/Resources/config/routing.yml"
    prefix:   /

カスタム設定
config/packages/presta_sitemap.yaml

presta_sitemap:
    alternate:
        enabled: true
        default_locale: 'en'
        locales: ['en', 'ja']
        i18n: symfony

キャッシュクリアと所有権修復

# bin/console cache:clear
# chown -R www-data:www-data ./

サイトマップのアウトプット

# bin/console presta:sitemaps:dump --base-url=https://ficus.myvnc.com/
Dumping all sections of sitemaps into public directory
Created/Updated the following sitemap files:
    sitemap.default.xml
    sitemap.xml

robots.txtの作成

About /robots.txt
https://www.robotstxt.org/robotstxt.html

global.cssの変更

/public/static/css/global.css

表示サイズ変更時の不具合

新規オブジェクト内で定義したwysiwygによるテキスト要素内で追加した画像サイズが、携帯モードにしてもそのまま。
ウェブページ表示内の画像サイズを携帯サイズの幅にも対応させるため global.css に以下追加。

.main-content img {
    max-width: 100%;
}

CKEditor Code Snippetの背景カラー

携帯幅サイズへ変更時、カーソルが付与されたセクションでカーソルを右移動すると背景が白のまま(cssでの指定背景色が反映されていない)。
codesnippet指定セクション <pre><code>.....</code></pre>

<pre>セクションで以下指定。

pre {
    display: block;
    padding: 10px;
    margin: 0 0 10.5px;
    font-size: 0.95rem;
    line-height: 1.5;
    word-break: break-all;
    word-wrap: break-word;
    color: #7b8a8b;
    background-color: #474948;
    border: 1px solid #ffffff;
    border-radius: 4px;
}

URLの改行

表示幅縮小時の https://............ の改行指定

a {
    overflow-wrap: break-word;
}

overflow-wrap無効時

overflow-wrap有効時

overflow-wrap

word-break

Error Redirect Page

指定URIエラー時のリダイレクト

Error-Pageを作成し、そのディレクトリを指定。

System Settings ---> Website
error_redirect

AWSへ移行時のエラー

500エラー発生。.envでデバックモードへ変更し下記エラー確認。Documentページの読み込みエラー。

PLUGIN_CMF_COLLECT_DOCUMENT_SEGMENT_ASSIGNMENTS(?)' with params [1]:

下記問題と同一

DROP FUNCTION IF EXISTS PLUGIN_CMF_COLLECT_DOCUMENT_SEGMENT_ASSIGNMENTS;
DELIMITER //

CREATE FUNCTION PLUGIN_CMF_COLLECT_DOCUMENT_SEGMENT_ASSIGNMENTS(elementIdent INT) RETURNS TEXT
  READS SQL DATA
  BEGIN
    DECLARE segmentIds TEXT;
    DECLARE elementExists TINYINT;
    DECLARE breaks TINYINT;

    SELECT `segments` FROM `plugin_cmf_segment_assignment` WHERE `elementId` = elementIdent AND `elementType` = 'document' INTO segmentIds;
    SELECT COUNT(*) FROM `plugin_cmf_segment_assignment` WHERE `elementId` = elementIdent AND `elementType` = 'document' INTO elementExists;
    SELECT `breaksInheritance` FROM `plugin_cmf_segment_assignment` WHERE `elementId` = elementIdent AND `elementType` = 'document' INTO breaks;

    WHILE (elementExists = 0 OR breaks IS NULL OR breaks <> 1) AND elementIdent > 1 DO
      SELECT `parentId`  FROM `documents` WHERE `id` = elementIdent INTO elementIdent;
      SELECT CONCAT_WS(',', segmentIds, (SELECT `segments` FROM `plugin_cmf_segment_assignment` WHERE `elementId` = elementIdent AND `elementType` = 'document')) INTO segmentIds;
      SELECT COUNT(*) FROM `plugin_cmf_segment_assignment` WHERE `elementId` = elementIdent AND `elementType` = 'document' INTO elementExists;
      SELECT `breaksInheritance` INTO breaks FROM `plugin_cmf_segment_assignment` WHERE `elementId` = elementIdent AND `elementType` = 'document';
    END WHILE;

    RETURN segmentIds;
  END//
DELIMITER ;

上記sqlコマンドをpimcoreのデータベースで実行。

GmailによるMailer設定

Pimcoreで使用するMailerGmailに設定します。

PImcoreEmail Framework

参照元:SymfonyMailerに関するドキュメント

以下PImcoreの設定ファイルのMailerの箇所をアンコメントして有効にして下さい。

config/config.yml

#### SYSTEM SETTINGS

    email:
        sender:
            name: 'Ficusonline'
            email: [email protected]
        return:
            name: ''
            email: ''

#### SYMFONY OVERRIDES
framework:

#### SYMFONY MAILER TRANSPORTS
    mailer:
        transports:
            main: '%env(MAILER_DSN)%'

GmailによるMailer設定は、別途 .env ファイルで指定。
.env

MAILER_DSN=gmail+smtp://USERNAME:PASSWORD@default

ComposerGmail Mailerをインストール。

# composer require symfony/google-mailer

最後にPimcoreによるサイトディレクトリのアクセス権 (500error対応) を修復して下さい。

bin/console command

キャッシュクリア

# bin/console cache:clear

キャッシュクリア後はアクセス権を見直すこと。

# chown -R www-data:www-data ./

コマンドオプション一覧

# bin/console
Pimcore 10.0.8 (env: prod, debug: false)

Usage:
  command [options] [arguments]

Options:
  -h, --help                     Display help for the given command. When no command is given display help for the list command
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi|--no-ansi           Force (or disable --no-ansi) ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --ignore-maintenance-mode  Set this flag to force execution in maintenance mode
      --maintenance-mode         Set this flag to force maintenance mode while this task runs
  -e, --env=ENV                  The Environment name. [default: "prod"]
      --no-debug                 Switch off debug mode.
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  about                                             Display information about the current project
  help                                              Display help for a command
  list                                              List commands
 app
  app:asset-copyright                               
  app:data-command                                  
 assets
  assets:install                                    Install bundle's web assets under a public directory
 cache
  cache:clear                                       Clear the cache
  cache:pool:clear                                  Clear cache pools
  cache:pool:delete                                 Delete an item from a cache pool
  cache:pool:list                                   List available cache pools
  cache:pool:prune                                  Prune cache pools
  cache:warmup                                      Warm up an empty cache
 cmf
  cmf:build-segments                                Build automatically calculated segments
  cmf:duplicates-index                              Handles the duplicate search index
  cmf:handle-cron-triggers                          Handle cron triggers cronjob - needs to run once per minute
  cmf:maintenance                                   Performs various tasks configured in services.yml -> 'cmf.maintenance.serviceCalls'
  cmf:process-actiontrigger-queue                   Process entries from action trigger queue
  cmf:segment-assignment-index                      Processes entries from segment assignment queue, use this for manually updating the index, which is usually done during cmf:maintenance
 config
  config:dump-reference                             Dump the default configuration for an extension
 datahub
  datahub:graphql:rebuild-definitions               Rebuild GraphQL endpoint definitions
 dbal
  dbal:run-sql                                      Executes arbitrary SQL directly from the command line.
 debug
  debug:autowiring                                  List classes/interfaces you can use for autowiring
  debug:config                                      Dump the current configuration for an extension
  debug:container                                   Display current services for an application
  debug:event-dispatcher                            Display configured listeners for an application
  debug:firewall                                    Display information about your security firewall(s)
  debug:form                                        Display form type information
  debug:router                                      Display current routes for an application
  debug:translation                                 Display translation messages information
  debug:twig                                        Show a list of twig functions, filters, globals and tests
  debug:validator                                   Display validation constraints for classes
 doctrine
  doctrine:database:create                          Creates the configured database
  doctrine:database:drop                            Drops the configured database
  doctrine:database:import                          Import SQL file(s) directly to Database.
  doctrine:migrations:current                       [current] Outputs the current version
  doctrine:migrations:diff                          [diff] Generate a migration by comparing your current database to your mapping information.
  doctrine:migrations:dump-schema                   [dump-schema] Dump the schema for your database to a migration.
  doctrine:migrations:execute                       [execute] Execute one or more migration versions up or down manually.
  doctrine:migrations:generate                      [generate] Generate a blank migration class.
  doctrine:migrations:latest                        [latest] Outputs the latest version
  doctrine:migrations:list                          [list-migrations] Display a list of all available migrations and their status.
  doctrine:migrations:migrate                       [migrate] Execute a migration to a specified version or the latest available version.
  doctrine:migrations:rollup                        [rollup] Rollup migrations by deleting all tracked versions and insert the one version that exists.
  doctrine:migrations:status                        [status] View the status of a set of migrations.
  doctrine:migrations:sync-metadata-storage         [sync-metadata-storage] Ensures that the metadata storage is at the latest version.
  doctrine:migrations:up-to-date                    [up-to-date] Tells you if your schema is up-to-date.
  doctrine:migrations:version                       [version] Manually add and delete migration versions from the version table.
  doctrine:query:sql                                Executes arbitrary SQL directly from the command line.
 ecommerce
  ecommerce:cleanup-pending-orders                  Cleans up orders with state pending payment after 1h -> delegates this to commit order processor
  ecommerce:indexservice:bootstrap                  Bootstrap tasks creating/updating index (for all tenants), use one of the options --create-or-update-index-structure or --update-index
  ecommerce:indexservice:elasticsearch-sync         Refresh elastic search (ES) index settings, mappings via native ES-API.
  ecommerce:indexservice:process-preparation-queue  Processes the ecommerce preparation queue based on the store table(s).
  ecommerce:indexservice:process-update-queue       Processes the ecommerce queue / store table and updates the (search) index.
  ecommerce:indexservice:reset-queue                Resets the preparation or index-update queue (ONLY NEEDED if store table is out of sync)
  ecommerce:voucher:cleanup-reservations            Cleans the token reservations due to sysConfig duration settings
  ecommerce:voucher:cleanup-statistics              House keeping for Voucher Usage Statistics - cleans up all old data.
 fos
  fos:js-routing:debug                              Displays currently exposed routes for an application
  fos:js-routing:dump                               Dumps exposed routes to the filesystem
 lint
  lint:container                                    Ensure that arguments injected into services match type declarations
  lint:twig                                         Lint a Twig template and outputs encountered errors
  lint:xliff                                        Lint an XLIFF file and outputs encountered errors
  lint:yaml                                         Lint a YAML file and outputs encountered errors
 pimcore
  pimcore:bundle:disable                            Disables a bundle
  pimcore:bundle:enable                             Enables a bundle
  pimcore:bundle:install                            Installs a bundle
  pimcore:bundle:list                               Lists all pimcore bundles and their enabled/installed state
  pimcore:bundle:uninstall                          Uninstalls a bundle
  pimcore:cache:clear                               Clear caches
  pimcore:cache:warming                             Warm up caches
  pimcore:classificationstore:delete-store          [classificationstore:delete-store] Delete Classification Store
  pimcore:definition:import:class                   [definition:import:class] Import Class definition from a JSON export
  pimcore:definition:import:customlayout            [definition:import:customlayout] Import Customlayout definition from a JSON export
  pimcore:definition:import:fieldcollection         [definition:import:fieldcollection] Import FieldCollection definition from a JSON export
  pimcore:definition:import:objectbrick             [definition:import:objectbrick] Import ObjectBrick definition from a JSON export
  pimcore:deployment:classes-rebuild                [deployment:classes-rebuild] rebuilds db structure for classes, field collections and object bricks based on updated var/classes/definition_*.php files
  pimcore:deployment:custom-layouts-rebuild         rebuilds db structure for custom layouts based on updated var/classes/customlayouts/definition_*.php files
  pimcore:documents:generate-page-previews          Generates the previews shown in the tree on hover
  pimcore:documents:migrate-elements                Migrates document elements to editables. See issue https://github.com/pimcore/pimcore/issues/7384 first
  pimcore:email:cleanup                             [email:cleanup] Cleanup email logs
  pimcore:image:low-quality-preview                 [pimcore:image:svg-preview] Regenerates low quality image previews for all image assets
  pimcore:locale:delete-unused-tables               Delete unused locale(invalid language) tables & views
  pimcore:maintenance                               [maintenance] Asynchronous maintenance jobs of pimcore (needs to be set up as cron job)
  pimcore:maintenance-mode                          Enable or disable maintenance mode
  pimcore:mysql-tools                               [mysql-tools] Optimize and warmup mysql database
  pimcore:run-script                                Run a specific PHP script in an initialized Pimcore environment
  pimcore:search-backend-reindex                    [search-backend-reindex] Re-indexes the backend search of pimcore
  pimcore:system:requirements:check                 [system:requirements:check] Check system requirements
  pimcore:thumbnails:clear                          Clear certain image or video thumbnails (temp. files)
  pimcore:thumbnails:image                          [thumbnails:image] Generate image thumbnails, useful to pre-generate thumbnails in the background
  pimcore:thumbnails:optimize-images                [thumbnails:optimize-images] Optimize filesize of all thumbnails
  pimcore:thumbnails:video                          [thumbnails:video] Generate video thumbnails, useful to pre-generate thumbnails in the background
  pimcore:user:reset-password                       [reset-password] Reset a user's password
  pimcore:web2print:pdf-creation                    [web2print:pdf-creation] Start pdf creation
  pimcore:workflow:dump                             Dump a workflow
 presta
  presta:sitemaps:dump                              Dumps sitemaps to given location
 router
  router:match                                      Help debug routes by simulating a path info match
 secrets
  secrets:decrypt-to-local                          Decrypt all secrets and stores them in the local vault
  secrets:encrypt-from-local                        Encrypt all local secrets to the vault
  secrets:generate-keys                             Generate new encryption keys
  secrets:list                                      List all secrets
  secrets:remove                                    Remove a secret from the vault
  secrets:set                                       Set a secret in the vault
 security
  security:encode-password                          Encode a password
  security:hash-password                            Hash a user password
 translation
  translation:pull                                  Pull translations from a given provider.
  translation:push                                  Push translations to a given provider.
  translation:update                                Update the translation file

Pimcore設定確認

# bin/console debug:config pimcore

Pimcore bundleの無効化

以下イーコマース関連のbundleは不要のため無効とする。

  • PimcoreCustomerManagementFrameworkBundle
  • PimcoreEcommerceFrameworkBundle
  • PimcorePaymentProviderUnzerBundle

以下bin/consoleコマンドオプションにてbundleリストを確認後無効化。

pimcore
  pimcore:bundle:disable                            Disables a bundle
  pimcore:bundle:enable                             Enables a bundle
  pimcore:bundle:install                            Installs a bundle
  pimcore:bundle:list                               Lists all pimcore bundles and their enabled/installed state
  pimcore:bundle:uninstall                          Uninstalls a bundle
  pimcore:cache:clear                               Clear caches
# ./bin/console pimcore:bundle:list
+------------------------------------------+---------+-----------+-------------+---------------+----------+---+
| Bundle                                   | Enabled | Installed | Installable | Uninstallable | Priority |   |
+------------------------------------------+---------+-----------+-------------+---------------+----------+---+
| PimcoreCustomerManagementFrameworkBundle | ❌       | ❌         | ❌           | ❌             | ❌        | 0 |
| OutputDataConfigToolkitBundle            | ✔       | ❌         | ✔           | ✔             | ✔        |   |
| PimcoreDataHubBundle                     | ✔       | ✔         | ❌           | ❌             | ✔        |   |
| PimcoreEcommerceFrameworkBundle          | ❌       | ❌         | ❌           | ❌             | ❌        | 0 |
| PimcorePaymentProviderUnzerBundle        | ❌       | ❌         | ❌           | ❌             | ❌        | 0 |
| NumberSequenceGeneratorBundle            | ❌       | ❌         | ❌           | ❌             | ❌        | 0 |
| ObjectMergerBundle                       | ✔       | ✔         | ❌           | ❌             | ✔        |   |
| Web2PrintToolsBundle                     | ✔       | ❌         | ✔           | ❌             | ✔        |   |
+------------------------------------------+---------+-----------+-------------+---------------+----------+---+

無効化

# ./bin/console pimcore:bundle:disable PimcorePaymentProviderUnzerBundle

Data Objects 500 Error

バージョン履歴のクリア

phpMyAdminのpimcoreデータベース内で以下sqlコマンド実行

DELETE FROM ###.versions WHERE ctype='asset';

全バージョン履歴のクリア

$ docker exec -ti pimcore10-fpm bash
# cd pimcore10
# ./bin/console pimcore:maintenance -f -j versioncleanup
# rm -r var/versions/object

管理画面エラー

ブラウザの検証メッセージ
pimcore_admin_document_document_doctypesget error on admin

デバックモードへ変更し管理画面へのログイン可否確認後、プロダクションモードへ変更。
キャッシュの不具合によるエラー。

# bin/console clear:cache

bin/console list

bin/console list       
Pimcore 10.0.8 (env: prod, debug: false)

Usage:
  command [options] [arguments]

Options:
  -h, --help                     Display help for the given command. When no command is given display help for the list command
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi|--no-ansi           Force (or disable --no-ansi) ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --ignore-maintenance-mode  Set this flag to force execution in maintenance mode
      --maintenance-mode         Set this flag to force maintenance mode while this task runs
  -e, --env=ENV                  The Environment name. [default: "prod"]
      --no-debug                 Switch off debug mode.
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  about                                             Display information about the current project
  help                                              Display help for a command
  list                                              List commands
 app
  app:asset-copyright                               
  app:data-command                                  
 assets
  assets:install                                    Install bundle's web assets under a public directory
 cache
  cache:clear                                       Clear the cache
  cache:pool:clear                                  Clear cache pools
  cache:pool:delete                                 Delete an item from a cache pool
  cache:pool:list                                   List available cache pools
  cache:pool:prune                                  Prune cache pools
  cache:warmup                                      Warm up an empty cache
 cmf
  cmf:build-segments                                Build automatically calculated segments
  cmf:duplicates-index                              Handles the duplicate search index
  cmf:handle-cron-triggers                          Handle cron triggers cronjob - needs to run once per minute
  cmf:maintenance                                   Performs various tasks configured in services.yml -> 'cmf.maintenance.serviceCalls'
  cmf:process-actiontrigger-queue                   Process entries from action trigger queue
  cmf:segment-assignment-index                      Processes entries from segment assignment queue, use this for manually updating the index, which is usually done during cmf:maintenance
 config
  config:dump-reference                             Dump the default configuration for an extension
 datahub
  datahub:graphql:rebuild-definitions               Rebuild GraphQL endpoint definitions
 dbal
  dbal:run-sql                                      Executes arbitrary SQL directly from the command line.
 debug
  debug:autowiring                                  List classes/interfaces you can use for autowiring
  debug:config                                      Dump the current configuration for an extension
  debug:container                                   Display current services for an application
  debug:event-dispatcher                            Display configured listeners for an application
  debug:firewall                                    Display information about your security firewall(s)
  debug:form                                        Display form type information
  debug:router                                      Display current routes for an application
  debug:translation                                 Display translation messages information
  debug:twig                                        Show a list of twig functions, filters, globals and tests
  debug:validator                                   Display validation constraints for classes
 doctrine
  doctrine:database:create                          Creates the configured database
  doctrine:database:drop                            Drops the configured database
  doctrine:database:import                          Import SQL file(s) directly to Database.
  doctrine:migrations:current                       [current] Outputs the current version
  doctrine:migrations:diff                          [diff] Generate a migration by comparing your current database to your mapping information.
  doctrine:migrations:dump-schema                   [dump-schema] Dump the schema for your database to a migration.
  doctrine:migrations:execute                       [execute] Execute one or more migration versions up or down manually.
  doctrine:migrations:generate                      [generate] Generate a blank migration class.
  doctrine:migrations:latest                        [latest] Outputs the latest version
  doctrine:migrations:list                          [list-migrations] Display a list of all available migrations and their status.
  doctrine:migrations:migrate                       [migrate] Execute a migration to a specified version or the latest available version.
  doctrine:migrations:rollup                        [rollup] Rollup migrations by deleting all tracked versions and insert the one version that exists.
  doctrine:migrations:status                        [status] View the status of a set of migrations.
  doctrine:migrations:sync-metadata-storage         [sync-metadata-storage] Ensures that the metadata storage is at the latest version.
  doctrine:migrations:up-to-date                    [up-to-date] Tells you if your schema is up-to-date.
  doctrine:migrations:version                       [version] Manually add and delete migration versions from the version table.
  doctrine:query:sql                                Executes arbitrary SQL directly from the command line.
 ecommerce
  ecommerce:cleanup-pending-orders                  Cleans up orders with state pending payment after 1h -> delegates this to commit order processor
  ecommerce:indexservice:bootstrap                  Bootstrap tasks creating/updating index (for all tenants), use one of the options --create-or-update-index-structure or --update-index
  ecommerce:indexservice:elasticsearch-sync         Refresh elastic search (ES) index settings, mappings via native ES-API.
  ecommerce:indexservice:process-preparation-queue  Processes the ecommerce preparation queue based on the store table(s).
  ecommerce:indexservice:process-update-queue       Processes the ecommerce queue / store table and updates the (search) index.
  ecommerce:indexservice:reset-queue                Resets the preparation or index-update queue (ONLY NEEDED if store table is out of sync)
  ecommerce:voucher:cleanup-reservations            Cleans the token reservations due to sysConfig duration settings
  ecommerce:voucher:cleanup-statistics              House keeping for Voucher Usage Statistics - cleans up all old data.
 fos
  fos:js-routing:debug                              Displays currently exposed routes for an application
  fos:js-routing:dump                               Dumps exposed routes to the filesystem
 lint
  lint:container                                    Ensure that arguments injected into services match type declarations
  lint:twig                                         Lint a Twig template and outputs encountered errors
  lint:xliff                                        Lint an XLIFF file and outputs encountered errors
  lint:yaml                                         Lint a YAML file and outputs encountered errors
 pimcore
  pimcore:bundle:disable                            Disables a bundle
  pimcore:bundle:enable                             Enables a bundle
  pimcore:bundle:install                            Installs a bundle
  pimcore:bundle:list                               Lists all pimcore bundles and their enabled/installed state
  pimcore:bundle:uninstall                          Uninstalls a bundle
  pimcore:cache:clear                               Clear caches
  pimcore:cache:warming                             Warm up caches
  pimcore:classificationstore:delete-store          [classificationstore:delete-store] Delete Classification Store
  pimcore:definition:import:class                   [definition:import:class] Import Class definition from a JSON export
  pimcore:definition:import:customlayout            [definition:import:customlayout] Import Customlayout definition from a JSON export
  pimcore:definition:import:fieldcollection         [definition:import:fieldcollection] Import FieldCollection definition from a JSON export
  pimcore:definition:import:objectbrick             [definition:import:objectbrick] Import ObjectBrick definition from a JSON export
  pimcore:deployment:classes-rebuild                [deployment:classes-rebuild] rebuilds db structure for classes, field collections and object bricks based on updated var/classes/definition_*.php files
  pimcore:deployment:custom-layouts-rebuild         rebuilds db structure for custom layouts based on updated var/classes/customlayouts/definition_*.php files
  pimcore:documents:generate-page-previews          Generates the previews shown in the tree on hover
  pimcore:documents:migrate-elements                Migrates document elements to editables. See issue https://github.com/pimcore/pimcore/issues/7384 first
  pimcore:email:cleanup                             [email:cleanup] Cleanup email logs
  pimcore:image:low-quality-preview                 [pimcore:image:svg-preview] Regenerates low quality image previews for all image assets
  pimcore:locale:delete-unused-tables               Delete unused locale(invalid language) tables & views
  pimcore:maintenance                               [maintenance] Asynchronous maintenance jobs of pimcore (needs to be set up as cron job)
  pimcore:maintenance-mode                          Enable or disable maintenance mode
  pimcore:mysql-tools                               [mysql-tools] Optimize and warmup mysql database
  pimcore:run-script                                Run a specific PHP script in an initialized Pimcore environment
  pimcore:search-backend-reindex                    [search-backend-reindex] Re-indexes the backend search of pimcore
  pimcore:system:requirements:check                 [system:requirements:check] Check system requirements
  pimcore:thumbnails:clear                          Clear certain image or video thumbnails (temp. files)
  pimcore:thumbnails:image                          [thumbnails:image] Generate image thumbnails, useful to pre-generate thumbnails in the background
  pimcore:thumbnails:optimize-images                [thumbnails:optimize-images] Optimize filesize of all thumbnails
  pimcore:thumbnails:video                          [thumbnails:video] Generate video thumbnails, useful to pre-generate thumbnails in the background
  pimcore:user:reset-password                       [reset-password] Reset a user's password
  pimcore:web2print:pdf-creation                    [web2print:pdf-creation] Start pdf creation
  pimcore:workflow:dump                             Dump a workflow
 presta
  presta:sitemaps:dump                              Dumps sitemaps to given location
 router
  router:match                                      Help debug routes by simulating a path info match
 secrets
  secrets:decrypt-to-local                          Decrypt all secrets and stores them in the local vault
  secrets:encrypt-from-local                        Encrypt all local secrets to the vault
  secrets:generate-keys                             Generate new encryption keys
  secrets:list                                      List all secrets
  secrets:remove                                    Remove a secret from the vault
  secrets:set                                       Set a secret in the vault
 security
  security:encode-password                          Encode a password
  security:hash-password                            Hash a user password
 translation
  translation:pull                                  Pull translations from a given provider.
  translation:push                                  Push translations to a given provider.
  translation:update                                Update the translation file

Pimcore Specialities and Examples

Controller Name File Name Class Name Default View Directory
Content src/Controller/ContentController.php App\Controller\ContentController /templates/content
News src/Controller/NewsController.php App\Controller\NewsController /templates/news

The Messanger Component

Messenger: Sync & Queued Message Handling

Deploying to Production

On production, there are a few important things to think about:

Use Supervisor to keep your worker(s) running

You’ll want one or more “workers” running at all times. To do that, use a process control system like Supervisor.

Don’t Let Workers Run Forever

Some services (like Doctrine’s EntityManager) will consume more memory over time. So, instead of allowing your worker to run forever, use a flag like messenger:consume --limit=10 to tell your worker to only handle 10 messages before exiting (then Supervisor will create a new process). There are also other options like --memory-limit=128M and --time-limit=3600.

Restart Workers on Deploy

Each time you deploy, you’ll need to restart all your worker processes so that they see the newly deployed code. To do this, run messenger:stop-workers on deployment. This will signal to each worker that it should finish the message it’s currently handling and should shut down gracefully. Then, Supervisor will create new worker processes. The command uses the app cache internally - so make sure this is configured to use an adapter you like.

Use the Same Cache Between Deploys

If your deploy strategy involves the creation of new target directories, you should set a value for the cache.prefix.seed configuration option in order to use the same cache namespace between deployments. Otherwise, the cache.app pool will use the value of the kernel.project_dir parameter as base for the namespace, which will lead to different namespaces each time a new deployment is made.

メインテナンス(クローンジョブ)

メッセンジャーはリソースを浪費するため、時間制限を設けること。

https://pimcore.com/docs/pimcore/current/Development_Documentation/Getting_Started/Installation.html#page_5-Maintenance-Cron-Job

# this command needs anyway executed via cron or similar task scheduler
# it fills the message queue with the necessary tasks, which are then processed by messenger:consume
*/5 * * * * /your/project/bin/console pimcore:maintenance --async

# it's recommended to run the following command using a process control system like Supervisor
# please follow the Symfony Messenger guide for a best practice production setup: 
# https://symfony.com/doc/current/messenger.html#deploying-to-production
*/5 * * * * /your/project/bin/console messenger:consume pimcore_core pimcore_maintenance --time-limit=300

サイトマップカスタムジェネレータ(Sitemap custom generator)

新規に定義したオブジェクトであるニュースやブログ記事のサイトマップの作成について

https://github.com/pimcore/pimcore/blob/10.x/doc/Development_Documentation/18_Tools_and_Features/39_Sitemaps.md#creating-a-custom-generator


注) 既に掲載した下記内容の補足記事


ニュース記事のサイトマップジェネレータ:サンプルデモ


設定ファイルの pimcore セクションにニュースとブログ記事のサイトマップジェネレータを指定したsitemaps を追加

config/config.yaml

pimcore:
.....
.....
.....
#### Sitemaps
    sitemaps:
        generators:
            app_news:
                enabled: true
                priority: 50
                generator_id: App\Sitemaps\NewsGenerator

            app_blog:
                enabled: true
                priority: 49
                generator_id: App\Sitemaps\BlogGenerator
                
            # Pimcore ships a default document tree generator which is enabled by default
            # but you can easily disable it here.
            pimcore_documents:
                enabled: true
.....
.....

config/services.yamlparameters セクションと services セクションにサイトマップジェネレータに関わるパラメータやクラスを指定

config/services.yaml

parameters:
.....
.....
    #this is necessary for CLI commands to get the base url, eg. sitemap dump
    router.request_context.host: www.example.com
    router.request_context.scheme: https
.....
.....
services:
.....
.....
# ---------------------------------------------------------
    # Processors
    # ---------------------------------------------------------
    App\Sitemaps\Processors\AbsoluteUrlProcessor: ~
    
    # ---------------------------------------------------------
    # sitemaps
    # ---------------------------------------------------------
    App\Sitemaps\NewsGenerator:
        arguments:
            $filters:
                - '@Pimcore\Sitemap\Element\Filter\PublishedFilter'
                - '@Pimcore\Sitemap\Element\Filter\PropertiesFilter'
            $processors:
                - '@App\Sitemaps\Processors\AbsoluteUrlProcessor'
                
    App\Sitemaps\BlogGenerator:
        arguments:
            $filters:
                - '@Pimcore\Sitemap\Element\Filter\PublishedFilter'
                - '@Pimcore\Sitemap\Element\Filter\PropertiesFilter'
            $processors:
                - '@App\Sitemaps\Processors\AbsoluteUrlProcessor'
.....
.....

ニュースのサイトマップジェネレータ作成

注) 'document' => Document::getByPath('/en/info/News') ドキュメントでのパス設定に注意。

src/Sitemaps/NewsGenerator.php

<?php

/**
 * Pimcore
 *
 * This source file is available under two different licenses:
 * - GNU General Public License version 3 (GPLv3)
 * - Pimcore Enterprise License (PEL)
 * Full copyright and license information is available in
 * LICENSE.md which is distributed with this source code.
 *
 *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
 *  @license    http://www.pimcore.org/license     GPLv3 and PEL
 */

namespace App\Sitemaps;

use Pimcore\Localization\LocaleServiceInterface;
use Pimcore\Model\DataObject\News;
use Pimcore\Model\Document;
use Pimcore\Sitemap\Element\AbstractElementGenerator;
use Pimcore\Sitemap\Element\GeneratorContext;
use Presta\SitemapBundle\Service\UrlContainerInterface;
use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class NewsGenerator extends AbstractElementGenerator
{
    public function __construct(protected LocaleServiceInterface $localeService, array $filters = [], array $processors = [])
    {
        parent::__construct($filters, $processors);
    }

    public function populate(UrlContainerInterface $urlContainer, string $section = null)
    {
        if (null !== $section && $section !== 'news') {
            // do not add entries if section doesn't match
            return;
        }

        $section = 'news';

        $list = new News\Listing();
        $list->setOrderKey('date');
        $list->setOrder('DESC');

        // the context contains metadata for filters/processors
        // it contains at least the url container, but you can add additional data
        // with the params parameter
        $context = new GeneratorContext($urlContainer, $section, ['foo' => 'bar']);

        //change locale as per multilingual setup
        $this->localeService->setLocale('en');

        /** @var News $newsArticle */
        foreach ($list as $newsArticle) {
            // only add element if it is not filtered
            if (!$this->canBeAdded($newsArticle, $context)) {
                continue;
            }

            // use a link generator to generate an URL to the article
            // you need to make sure the link generator generates an absolute url
            $link = $newsArticle->getClass()->getLinkGenerator()->generate($newsArticle, [
                'referenceType' => UrlGeneratorInterface::ABSOLUTE_URL,
                'document' => Document::getByPath('/en/info/News')
            ]);

            // create an entry for the sitemap
            $url = new UrlConcrete($link);

            // run url through processors
            $url = $this->process($url, $newsArticle, $context);

            // processors can return null to exclude the url
            if (null === $url) {
                continue;
            }

            // add the url to the container
            $urlContainer->addUrl($url, $section);
        }
    }
}

ブログ記事のサイトマップジェネレータ作成

src/Sitemaps/BlogGenerator.php

<?php

/**
 * Pimcore
 *
 * This source file is available under two different licenses:
 * - GNU General Public License version 3 (GPLv3)
 * - Pimcore Enterprise License (PEL)
 * Full copyright and license information is available in
 * LICENSE.md which is distributed with this source code.
 *
 *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
 *  @license    http://www.pimcore.org/license     GPLv3 and PEL
 */

namespace App\Sitemaps;

use Pimcore\Localization\LocaleServiceInterface;
use Pimcore\Model\DataObject\Blog;
use Pimcore\Model\Document;
use Pimcore\Sitemap\Element\AbstractElementGenerator;
use Pimcore\Sitemap\Element\GeneratorContext;
use Presta\SitemapBundle\Service\UrlContainerInterface;
use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class BlogGenerator extends AbstractElementGenerator
{
    
    public function __construct(protected LocaleServiceInterface $localeService, array $filters = [], array $processors = [])
    {
        parent::__construct($filters, $processors);
    }
                        
    public function populate(UrlContainerInterface $urlContainer, string $section = null)
    {
        if (null !== $section && $section !== 'blog') {
            // do not add entries if section doesn't match
            return;
        }

        $section = 'blog';

        $list = new Blog\Listing();
        $list->setOrderKey('date');
        $list->setOrder('DESC');

        // the context contains metadata for filters/processors
        // it contains at least the url container, but you can add additional data
        // with the params parameter
        $context = new GeneratorContext($urlContainer, $section, ['foo' => 'bar']);

        //change locale as per multilingual setup
        $this->localeService->setLocale('en');

        /** @var Blog $blogArticle */
        foreach ($list as $blogArticle) {
            // only add element if it is not filtered
            if (!$this->canBeAdded($blogArticle, $context)) {
                continue;
            }

            // use a link generator to generate an URL to the article
            // you need to make sure the link generator generates an absolute url
            $link = $blogArticle->getClass()->getLinkGenerator()->generate($blogArticle, [
                'referenceType' => UrlGeneratorInterface::ABSOLUTE_URL,
                'document' => Document::getByPath('/en/Blog')
            ]);

            // create an entry for the sitemap
            $url = new UrlConcrete($link);

            // run url through processors
            $url = $this->process($url, $blogArticle, $context);

            // processors can return null to exclude the url
            if (null === $url) {
                continue;
            }

            // add the url to the container
            $urlContainer->addUrl($url, $section);
        }
    }
}

絶対パスによるサイトマップ作成のための Processor を作成

src/Sitemaps/Processors/AbsoluteUrlProcessor.php

<?php

declare(strict_types=1);

/**
 * Pimcore
 *
 * This source file is available under two different licenses:
 * - GNU General Public License version 3 (GPLv3)
 * - Pimcore Commercial License (PCL)
 * Full copyright and license information is available in
 * LICENSE.md which is distributed with this source code.
 *
 *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
 *  @license    http://www.pimcore.org/license     GPLv3 and PCL
 */

namespace App\Sitemaps\Processors;

use Pimcore\Model\Element\ElementInterface;
use Pimcore\Sitemap\Element\GeneratorContextInterface;
use Pimcore\Sitemap\Element\ProcessorInterface;
use Pimcore\Sitemap\UrlGeneratorInterface;
use Presta\SitemapBundle\Sitemap\Url\Url;
use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;

class AbsoluteUrlProcessor implements ProcessorInterface
{
    /**
     * @var UrlGeneratorInterface
     */
    private $urlGenerator;

    public function __construct(UrlGeneratorInterface $urlGenerator)
    {
        $this->urlGenerator = $urlGenerator;
    }

    public function process(Url $url, ElementInterface $element, GeneratorContextInterface $context)
    {
        $path = $this->urlGenerator->generateUrl($url->getLoc());
        $url  = new UrlConcrete($path);

        return $url;
    }
}

キャッシュをクリアしアクセス権を修復

# cd project_folder
# bin/console cache:clear
# chown -R www-data:www-data ./

サイトマップを出力

# bin/console presta:sitemaps:dump
Dumping sitemaps section blog into project_folder/public directory
Created/Updated the following sitemap files:
    sitemap.default.xml
    sitemap.news.xml
    sitemap.blog.xml
    sitemap.xml

ニュースまたはブログの各サイトマップジェネレータで指定したセクションを指定して出力

# bin/console presta:sitemaps:dump --section=news
or
# bin/console presta:sitemaps:dump --section=blog

多言語対応の場合、以下ファイルを追加で作成

config/packages/presta_sitemap.yaml

presta_sitemap:
    alternate:
        enabled: true
        default_locale: 'en'
        locales: ['en', 'ja']
        i18n: symfony

サイトマップバンドルの設定確認

# bin/console clear:cache
# chown -R www-data:www-data

# bin/console debug:config PrestaSitemapBundle

Current configuration for "PrestaSitemapBundle"
===============================================

presta_sitemap:
    defaults:
        lastmod: null
        priority: null
        changefreq: null
    alternate:
        enabled: true
        default_locale: en
        locales:
            - en
            - ja
        i18n: symfony
    generator: presta_sitemap.generator_default
    dumper: presta_sitemap.dumper_default
    timetolive: 3600
    sitemap_file_prefix: sitemap
    items_by_set: 50000
    route_annotation_listener: true
    dump_directory: xxx/xxx/project/public
    default_section: default

layout.html.twig

<head>
.....
.....
    {% do pimcore_head_script().appendFile('https://code.jquery.com/jquery-3.6.1.slim.min.js',null,null,{ integrity:"sha384-MYL22lstpGhSa4+udJSGro5I+VfM13fdJfCbAzP9krCEoK5r2EDFdgTg2+DGXdj+",crossorigin:"anonymous"}) %}
.....
.....
</head>