### Initialize DDEV Project and Install Drupal
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Standard DDEV commands to configure a project, start the environment, install Drupal using Composer, and set up Drush.
```sh
mkdir d10m && cd d10m
ddev config --project-type=drupal10 --docroot=web
ddev start
ddev composer create drupal/recommended-project:^10
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
ddev launch
```
--------------------------------
### Clone Drupal Starter Project and Start
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Clone a pre-configured Drupal starter project, start DDEV, install Drupal, set up local settings and config sync, and import configuration.
```sh
git clone git@github.com:selwynpolit/drupalstarter.git my-drupal-site
cd my-drupal-site
ddev start
ddev drush site:install --account-name=admin --account-pass=admin -y
# setup settings.local.php as above
# setup your config sync directory
ddev cim -y
```
--------------------------------
### DDEV Drupal 10 Project Setup
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Commands to set up a new Drupal 10 project with DDEV, including configuration, starting the environment, installing Drupal, and adding Drush.
```sh
mkdir dmulti && cd dmulti
ddev config --project-type=drupal10 --docroot=web
ddev start
ddev composer create drupal/recommended-project:^10
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
ddev launch
# or automatically log in with
ddev launch $(ddev drush uli)
```
--------------------------------
### Install Drupal 11 with DDEV
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Commands to configure and start a new Drupal 11 site using DDEV. This includes setting the PHP version and installing Drupal.
```sh
mkdir my-drupal-site && cd my-drupal-site
ddev config --project-type=drupal11 --php-version=8.3 --docroot=web
ddev start
ddev composer create drupal/recommended-project:^11
ddev composer require drush/drush
ddev drush site:install --account-name=admin --account-pass=admin -y
# Display a one-time link (CTRL/CMD + Click) from the command below to log in and edit your admin account details.
ddev drush uli
## Or this will open a browser and you can log in with username: `admin` and password: `admin`
ddev launch
# Or automatically log in with
ddev launch $(ddev drush uli)
```
--------------------------------
### Install Node.js and Dependencies
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/contribute.md
Installs the latest Node.js version, globally installs pnpm, and then installs project dependencies. Ensure nvm is installed and configured.
```sh
nvm install node
npm install -g pnpm
pnpm install
```
--------------------------------
### Copy Example Local Settings
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Copy the example local settings file to your default directory. This file will be used for local development configurations.
```sh
cp web/sites/example.settings.local.php web/sites/default/settings.local.php
```
--------------------------------
### Install All Composer Dependencies
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/composer.md
Run `composer install` to install all dependencies, including those in the `require-dev` section, typically used for local development.
```sh
composer install
```
```sh
composer install --dev
```
--------------------------------
### nc Output Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Example output from `nc -z localhost 9000` indicating a successful connection to port 9000.
```text
Connection to localhost port 9000 [tcp/cslistener] succeeded!
```
--------------------------------
### Install Oh My Zsh
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/setup_mac.md
Installs Oh My Zsh, a framework for managing Zsh configuration, by downloading and executing an installation script.
```bash
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
```
--------------------------------
### YAML Configuration File Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/config.md
Example of a YAML file storing configuration data, typically found in the config sync directory.
```yaml
pizza_rest_endpoint: 'https://pbx.pizza.com/pbx-service/'
```
--------------------------------
### Copy .env Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/dtt.md
Copies the example .env file to .env, which can be used to configure environment variables for DDev projects.
```bash
cd web/core
cp .env.example .env
```
--------------------------------
### Install ESLint for JavaScript Consistency
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/javascript.md
These bash commands install ESLint and the Drupal configuration, then run ESLint on custom modules and themes. Ensure Node.js, npm, and npx are installed first.
```bash
# Before running these commands, install node.js, npm, and npx
npm install eslint --save-dev
npm i eslint-config-drupal
npx eslint modules/custom/
npx eslint themes/custom/
```
--------------------------------
### lsof Output Example (php-fpm)
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Example output from `lsof -i TCP:9000` showing `php-fpm` listening on the Xdebug port.
```text
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php-fpm 732 selwyn 7u IPv4 0x4120ed57a07e871f 0t0 TCP
localhost:cslistener (LISTEN)
php-fpm 764 selwyn 8u IPv4 0x4120ed57a07e871f 0t0 TCP
localhost:cslistener (LISTEN)
php-fpm 765 selwyn 8u IPv4 0x4120ed57a07e871f 0t0 TCP
localhost:cslistener (LISTEN)
```
--------------------------------
### netstat Output Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Example output from `netstat -an | grep 9000` indicating a listener on port 9000.
```text
tcp46 0 0 *.9000 *.* LISTEN
```
--------------------------------
### lsof Output Example (PhpStorm)
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Example output from `lsof -i TCP:9000` showing PhpStorm listening on the Xdebug port.
```text
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
phpstorm 24380 selwyn 525u IPv6 0xb7fc31a42f1fb36d 0t0 TCP *:cslistener (LISTEN)
```
--------------------------------
### Install Subsite using DDEV Drush
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Use the `ddev drush site:install` command to install a subsite. This command requires specifying database URL, admin credentials, site name, database prefix, and subdirectory.
```sh
ddev drush site:install --db-url=mysql://db:db@db:3306/db --account-name=admin --account-pass=admin --site-name="Subsite 3" --db-prefix=subsite3_ --sites-subdir=subsite3 --site-mail=subsite3@example.com
```
--------------------------------
### Install ngrok Utility
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/setup_mac.md
Installs ngrok, a tool for securely exposing local servers to the internet, often used with ddev share.
```bash
brew install ngrok
```
--------------------------------
### Example Custom List Style View Template Path
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/twig.md
An example of a custom template file path for a specific view with a list style.
```path
~/Sites/dirt/web/themes/custom/dirt_bootstrap/templates/views/views-view-list--resource-library.html.twig
```
--------------------------------
### PHPUnit Output Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/dtt.md
Example output from running the TeamTest with PHPUnit, showing test results and variable dump.
```text
PHPUnit 9.5.24 #StandWithUkraine
Runtime: PHP 8.1.9
Configuration: /Users/selwyn/Sites/tea/phpunit.xml
.
1 / 1 (100%)
array(11) {
uid = string(4) 5101
fullname = string(12) Voter 1 Test
name = string(7) Voter 1
mail = string(24) voter1@mightycitizen.com
status = string(1) 1
firstname = string(7) Voter 1
lastname = string(4) Test
title = NULL
phone = NULL
roles = array(2) {
0 = string(13) authenticated
1 = string(9) srp_voter
}
voter_role = string(8) educator
}
Time: 00:00.773, Memory: 44.50 MB
OK (1 test, 5 assertions)
```
--------------------------------
### Composer.json require-dev Section Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/composer.md
An example of the `require-dev` section in a `composer.json` file, listing development-specific packages.
```json
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"drupal/coder": "^8.3",
"drupal/core-dev": "^10.3",
"drupal/devel": "^5.2",
"squizlabs/php_codesniffer": "^3.7"
},
```
--------------------------------
### Site Configuration Example using ControllerBase
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/routes.md
Fetches site name, slogan, and email from system.site configuration using the config shortcut.
```php
// Get the site name, slogan and email from the system.site config.
$config = $this->config('system.site');
$site_name = $config->get('name');
$slogan = $config->get('slogan');
$email = $config->get('mail');
```
--------------------------------
### Install Drupal Core Dev Dependencies
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/dtt.md
Install the drupal/core-dev package to get PHPUnit and other development tools. Use --dev and --update-with-all-dependencies to ensure all necessary packages are installed.
```bash
composer require drupal/core-dev --dev --update-with-all-dependencies
```
--------------------------------
### PHPUnit Test Execution Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/dtt.md
Example output of running PHPUnit tests, showing test status, runtime, and memory usage.
```text
> $ vendor/bin/phpunit
> docroot/modules/custom/tea_teks/modules/tea_teks_voting/tests/src/ExistingSite/VotingPageTest.php
PHPUnit 9.5.24 #StandWithUkraine
Runtime: PHP 8.1.9
Configuration: /Users/selwyn/Sites/tea/phpunit.xml
. 1 / 1 (100%)
Time: 00:00.830, Memory: 46.50 MB
OK (1 test, 3 assertions)
```
--------------------------------
### Install Module After Resolving Dependencies
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/composer.md
After successfully updating conflicting dependencies, attempt to install the target module again. This example shows the successful installation of `drupal/csv_serialization` version 4.0.0 after resolving the previous conflict.
```sh
composer require 'drupal/csv_serialization:^4.0'
./composer.json has been updated
Running composer update drupal/csv_serialization
Gathering patches for root package.
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 1 update, 0 removals
- Upgrading drupal/csv_serialization (3.0.0 => 4.0.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
- Downloading drupal/csv_serialization (4.0.0)
Gathering patches for root package.
Gathering patches for dependencies. This might take a minute.
- Upgrading drupal/csv_serialization (3.0.0 => 4.0.0): Extracting archive
Package webmozart/path-util is abandoned, you should avoid using it. Use symfony/filesystem instead.
Generating autoload files
99 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
phpstan/extension-installer: Extensions installed
Found 1 security vulnerability advisory affecting 1 package.
Run "composer audit" for a full list of advisories.
```
--------------------------------
### MySQL Command Line Client Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/queries.md
Example of connecting to a MySQL database using the command line client and executing a query to list table sizes.
```sh
ddev drush sqlc
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 134650
Server version: 5.7.42-0ubuntu0.18.04.1-log (Ubuntu)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [db]> SELECT table_name, round(((data_length + index_length) / 1024 / 1024), 2) as SIZE_MB FROM information_schema.TABLES WHERE table_schema = DATABASE() ORDER BY SIZE_MB DESC LIMIT 10;
```
--------------------------------
### Drush Update Database Command Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/upgrade.md
This is an example of the output from `drush updb` when deprecated core modules are still installed, indicating a need for removal.
```bash
$ drush updb
[error] (Currently using Removed core modules You must add the following contributed modules and reload this page.
* CKEditor [1]
* Color [2]
* Quick Edit [3]
* RDF [4]
These modules are installed on your site but are no longer provided by Core.
For more information, read the documentation on deprecated modules. [5]
[1] https://www.drupal.org/project/ckeditor
[2] https://www.drupal.org/project/color
[3] https://www.drupal.org/project/quickedit
[4] https://www.drupal.org/project/rdf
[5] https://www.drupal.org/node/3223395#s-recommendations-for-deprecated-modules
)
```
--------------------------------
### Install and Configure NVM (Node Version Manager)
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/setup_mac.md
Install NVM using Homebrew and set up the NVM directory. Add NVM to your shell's configuration file to load it automatically.
```bash
brew install nvm
```
```bash
mkdir ~/.nvm
```
```bash
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh" # This loads nvm
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion
```
```bash
nvm --version
0.39.7
```
```bash
nvm install node
```
--------------------------------
### Copy settings.local.php
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Copy the example local settings file to the default directory. This is the first step in configuring local development settings.
```bash
$ cp sites/example.settings.local.php sites/default/settings.local.php
```
--------------------------------
### Get Installed Module Version using Drush
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/hooks.md
Use Drush to retrieve the currently installed update version for a specific module. Replace 'my_module' with the actual module name.
```bash
# Get the installed version of a module
drush ev "echo \Drupal::service('update.update_hook_registry')->getInstalledVersion('my_module');"
```
--------------------------------
### Drush Command File Example
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/drush.md
A complete Drush command file demonstrating command definition, argument and option handling, and service injection.
```php
get('token'),
$container->get('entity_type.manager'),
);
}
/**
* Command description here.
*/
#[CLI\Command(name: 'drush_play2:command-name', aliases: ['foo'])]
#[CLI\Argument(name: 'arg1', description: 'Argument description.')]
#[CLI\Option(name: 'option-name', description: 'Option description')],
#[CLI\Usage(name: 'drush_play2:command-name foo', description: 'Usage description')],
public function commandName($arg1, $options = ['option-name' => 'default']) {
$this->logger()->success(dt('Achievement unlocked.'));
}
/**
* An example of the table output format.
*/
#[CLI\Command(name: 'drush_play2:token', aliases: ['token'])]
#[CLI\FieldLabels(labels: [
'group' => 'Group',
'token' => 'Token',
'name' => 'Name'
])]
#[CLI\DefaultTableFields(fields: ['group', 'token', 'name'])]
#[CLI\FilterDefaultField(field: 'name')],
public function token($options = ['format' => 'table']): RowsOfFields {
$all = $this->token->getInfo();
foreach ($all['tokens'] as $group => $tokens) {
foreach ($tokens as $key => $token) {
$rows[] = [
'group' => $group,
'token' => $key,
'name' => $token['name'],
];
}
}
return new RowsOfFields($rows);
}
}
```
--------------------------------
### Install Acquia CLI (acli)
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/setup_mac.md
Download and install the Acquia Command Line Interface (acli) tool. Ensure the 'bin' directory is in your PATH for accessibility.
```bash
curl -OL https://github.com/acquia/cli/releases/latest/download/acli.phar
```
```bash
chmod +x acli.phar
```
```bash
mv acli.phar ~/bin
```
```bash
acli auth:login
```
```bash
mkdir ~/bin
```
```bash
export PATH="$HOME/bin:$PATH"
```
--------------------------------
### Get Total Size of Drupal Files Directory
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/general.md
Use this command to get a human-readable summary of the total disk space used by the Drupal files directory. Ensure the path is correct for your Drupal installation.
```sh
du -sh /var/www/html/docroot/sites/default/files/
```
--------------------------------
### Start Local Development Server
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/contribute.md
Starts the Vitepress development server to preview changes locally. Access the site via the provided URL or by pressing 'o'. Use 'h' for help.
```sh
pnpm run book:dev
```
--------------------------------
### Install Hook to Set System Mail Interface
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/services.md
An example of a Drupal install hook that modifies the system mail configuration to use a custom mail plugin. It checks if the 'hello_world' plugin already exists before adding it.
```php
/*
* \Drupal::configFactory() retrieves the configuration factory.
*
* This is mostly used to change the override settings on the configuration
* factory. For example, changing the language or turning all overrides on
* or off.
*/
/**
* Implements hook_install().
*/
function hello_world_install() {
$config = \Drupal::configFactory()->getEditable('system.mail');
$mail_plugins = $config->get('interface');
if (in_array('hello_world', array_keys($mail_plugins))) {
return; }
$mail_plugins['hello_world'] = 'hello_world_mail';
$config->set('interface', $mail_plugins);
$config->save();
}
```
--------------------------------
### Perform a GET request using Drupal::httpClient
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/off-island.md
This example demonstrates how to initialize the HTTP client and make a GET request to retrieve data from an external API. It shows how to access the response body and decode JSON data.
```php
public function example1() {
//Initialize client;
$client = \Drupal::httpClient();
$uri = 'https://demo.ckan.org/api/3/action/package_list';
// Returns a GuzzleHttp\Psr7\Response.
$response = $client->request('GET', 'https://demo.ckan.org/api/3/action/package_list');
// Or using the magic method.
$response = $client->get($uri);
// Returns a GuzzleHttp\Psr7\Stream.
$stream = $response->getBody();
$json_data = Json::decode($stream);
$help = $json_data['help'];
$success = $json_data['success'];
$result = $json_data['result'][0];
$msg = "
URI: " . $uri;
$msg .= "
Help: " . $help;
$msg .= "
Success: " . $success;
$msg .= "
Result: " . $result;
$build['content'] = [
'#type' => 'item',
'#markup' => $this->t($msg),
];
return $build;
}
```
--------------------------------
### Generate One-Time Login for Main Site
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Use this command to get a one-time login link for the primary site in a multisite setup.
```sh
ddev drush uli
https://d10m.ddev.site/user/reset/1/1746197983/FzB_nebAqHFZmdsBJXpjYC_wjx7RAgjL352qZyaz81M/login
```
--------------------------------
### Load Zsh Plugins
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/setup_mac.md
Specify the plugins to load when Zsh starts. Add plugins wisely, as too many can slow down shell startup.
```zsh
plugins=(git)
```
```zsh
plugins=(git z macos zsh-autosuggestions zsh-syntax-highlighting sudo)
```
```zsh
plugins=(git osx zsh-syntax-highlighting)
```
--------------------------------
### Get Current Document Root Path
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/links.md
Obtains the real path to the document root of the Drupal installation. Useful for file system operations.
```php
$image_path = \Drupal::service('file_system')->realpath();
```
--------------------------------
### Example Script Execution and Output
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/general.md
This demonstrates how to execute the './find-broken-links.sh' script with a log file and shows a sample of its output, indicating the source page and the broken URL found.
```bash
./find-broken-links.sh wget.log
```
```text
Source: https://www.austinprogressivecalendar.com/node/92
Broken: https://www.austinprogressivecalendar.com/sites/default/files/styles/huge/public/inserted-images/content_landod8_2019-02-08_13-23-14.png?itok=h9R-_TbV
Source: https://www.austinprogressivecalendar.com/node/92
Broken: https://www.austinprogressivecalendar.com/sites/default/files/styles/medium/public/inserted-images/content_landod8_2019-02-08_13-23-14.png?itok=yyuKDoPc
Source: https://www.austinprogressivecalendar.com/node/92
Broken: https://www.austinprogressivecalendar.com/sites/default/files/styles/huge/public/inserted-images/incoming_connection_from_xdebug_2019-02-08_13-44-31.png?itok=1YPHA40R
```
--------------------------------
### Retrieve Drupal Date Range Field Values
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/dates.md
Access the start and end values of a date range field using magic getters, get(), or getValue().
```php
// Magic getters.
$start = $event_node->field_event_date_range->value
$end = $event_node->field_event_date_range->end_value
```
```php
// Using get().
$start = $event_node->get('field_event_date_range')->value
$end = $event_node->get('field_event_date_range')->end_value
```
```php
// Using getValue().
$start = $event_node->get('field_event_date_range')->getValue()[0]['value'];
$end = $event_node->get('field_event_date_range')->getValue()[0]['end_value'];
```
--------------------------------
### Define Batch Operations and Parameters
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/bq.md
This example shows how to define a batch with multiple operations, passing parameters to the first operation. The `file` key specifies the path to the file containing the batch functions.
```php
$batch = [
'title' => t('Exporting'),
'operations' => [
['my_function_1', [$account->id(), 'story']],
['my_function_2', []],
],
'finished' => 'my_finished_callback',
'file' => 'path_to_file_containing_my_functions',
];
batch_set($batch);
// Only needed if not inside a form _submit handler.
// Setting redirect in batch_process.
batch_process('node/1');
```
--------------------------------
### Routing for Modal Examples
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/modals.md
Defines routes for displaying modal dialogs. 'modal_examples.example1' renders links to open modals, while 'modal_examples.modal1' is a route that can display a modal directly, accepting parameters like 'program_id' and 'type'.
```yaml
# Controller with buttons to open modals
modal_examples.example1:
path: '/modal-examples/example1'
defaults:
_title: 'Modal Examples (example1)'
_controller: '\Drupal\modal_examples\Controller\ModalExamplesController::buildExample1'
requirements:
_permission: 'access content'
# first modal
modal_examples.modal1:
path: '/modal-examples/modal1/{program_id}/{type}'
defaults:
_title: 'Modal 1 with parameters'
_controller: '\Drupal\modal_examples\Controller\ModalExamplesController::buildModal1'
requirements:
_permission: 'access content'
options:
parameters:
program_id:
type:
no_cache: 'TRUE'
# Second modal
# You can't use this route directly
```
--------------------------------
### Implement hook_node_presave for Node Manipulation
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/nodes-and-fields.md
Use hook_node_presave to modify node data before it is saved. This example handles 'catastrophe_notice' content type, calculating end dates and setting titles based on governmental body and start date. It also populates initial start and end dates for extensions.
```php
/**
* Implements hook_ENTITY_TYPE_presave().
*/
function ogg_mods_node_presave(NodeInterface $node) {
switch ($node->getType()) {
case 'catastrophe_notice':
$end_date = NULL != $node->get('field_cn_start_end_dates')->end_value ? $node->get('field_cn_start_end_dates')->end_value : 'n/a';
$govt_body = NULL != $node->field_cn_governmental_body->value ? $node->field_cn_governmental_body->value : 'Unnamed Government Body';
$start_date_val = $node->get('field_cn_start_date')->value;
$accountProxy = "
// Anonymous users automatically fill out the end_date.
if (!$account->hasPermission('administer catastrophe notice')) {
$days = intval($node->get('field_cn_suspension_length')->value) - 1;
$end_date = DrupalDateTime::createFromFormat('Y-m-d', $start_date_val);
$end_date->modify("+$days days");
$end_date = $end_date->format("Y-m-d");
$node->set('field_cn_end_date', $end_date);
}
// Always reset the title.
$title = substr($govt_body, 0, 200) . " - $start_date_val";
$node->setTitle($title);
/*
* Fill in Initial start and end dates if this is an extension of
* a previously submitted notice.
*/
$extension = $node->get('field_cn_extension')->value;
if ($extension) {
$previous_notice_nid = $node->get('field_cn_original_notice')->target_id;
$previous_notice = Node::load($previous_notice_nid);
if ($previous_notice) {
$initial_start = $previous_notice->get('field_cn_start_date')->value;
$initial_end = $previous_notice->get('field_cn_end_date')->value;
$node->set('field_cn_initial_start_date', $initial_start);
$node->set('field_cn_initial_end_date', $initial_end);
}
}
break;
}
}
```
--------------------------------
### Install jq (JSON Processor)
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/setup_mac.md
Install 'jq', a lightweight and flexible command-line JSON processor. It's useful for parsing and manipulating JSON data.
```bash
brew install jq
```
--------------------------------
### Submit Form and Get Values
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/forms.md
This function is called when a user submits the form. Extract entries from `$form_state` to process them. This example uses the State API to store values.
```php
$values = $form_state->getValues();
$address1 = $values['footer_address1'];
$address2 = $values['footer_address2'];
$address3 = $values['footer_address3'];
$email = $values['email'];
$logo_url = $values['logo_url'];
$facebook = $values['facebook'];
$linkedin = $values['linkedin'];
$instagram = $values['instagram'];
$twitter = $values['twitter'];
$youtube = $values['youtube'];
```
--------------------------------
### Upgrading DDEV with Homebrew
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/development.md
Command to upgrade the DDEV installation using Homebrew. After upgrading, it's recommended to run `ddev stop` and `ddev start` to reconfigure the project.
```bash
brew upgrade ddev
```
--------------------------------
### Symfony Route Definition with PHP Attributes
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/routes.md
A basic Symfony controller example demonstrating route definition using PHP attributes. Ensure you have the necessary Symfony components installed.
```php
// src/Controller/BlogController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class BlogController extends AbstractController
{
#[Route('/blog', name: 'blog_list')]
public function list(): Response
{
// ...
}
}
```
--------------------------------
### Remove 'Team Content' Prefix with Regex in PHP
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/php.md
This example shows how to remove a specific string, like 'Team Content', from the start of a string using `preg_replace` and a case-insensitive flag.
```php
// Remove Team Content regardless of case from the beginning of a string.
// #i is the case-insensitive flag.
$bundle_label = preg_replace('#^(Team Content)#i', 'Team', $bundle_label);
```
--------------------------------
### Controller example for multiTest
Source: https://github.com/selwynpolit/d9book/blob/gh-pages/book/nodes-and-fields.md
A comprehensive example from a controller demonstrating various uses of `smartMultiValueFieldSetter` with both text and entity reference fields, including taxonomy fields.
```php
public function multiTest() {
$str = '