Created
July 21, 2016 10:30
-
-
Save marcvangend/7fd7a3f503ff8616a0c076ac5fa2dd2e to your computer and use it in GitHub Desktop.
Drupal 8: Custom path aliases exported to code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Install, update and uninstall functions for my module. | |
*/ | |
use Drupal\Core\Database\Database; | |
use Drupal\Core\Language\LanguageInterface; | |
/** | |
* Implements hook_install(). | |
*/ | |
function mymodule_install() { | |
mymodule_import_aliases(); | |
} | |
/** | |
* Add custom path aliases. | |
*/ | |
function mymodule_update_8001() { | |
return mymodule_import_aliases(); | |
} | |
/** | |
* @return array[] | |
* An array of arrays with the following structure: | |
* @code | |
* array( | |
* array( | |
* 'source' => '/calendar', // source path | |
* 'alias' => '/agenda', // path alias | |
* 'langcode' => 'nl', // language code for the alias (optional) | |
* ) | |
* ) | |
* @endcode | |
*/ | |
function mymodule_get_exported_aliases() { | |
return [ | |
[ | |
'source' => '/calendar', | |
'alias' => '/agenda', | |
'langcode' => 'nl', | |
], | |
]; | |
} | |
/** | |
* Process the list of exported path aliases and save them to the database, | |
*/ | |
function mymodule_import_aliases() { | |
// Get a list of aliases to be imported. | |
$aliases = mymodule_get_exported_aliases(); | |
// Save aliases. | |
foreach ($aliases as $alias) { | |
// Merge in defaults. | |
$alias += [ | |
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, | |
'pid' => NULL, | |
]; | |
// Check if the path alias already exists. | |
$query = 'SELECT COUNT(pid) FROM {url_alias} ua WHERE ua.alias = :alias AND ua.langcode = :langcode'; | |
$args = [':alias' => $alias['alias'], ':langcode' => $alias['langcode']]; | |
$count = Database::getConnection()->query($query, $args)->fetchField(); | |
// If the count is 0, we can proceed to insert the alias. | |
if ((int)$count === 0) { | |
mymodule_add_path_alias($alias['source'], $alias['alias'], $alias['langcode'], $alias['pid']); | |
} | |
// If the alias exists, remember the alias and its language. | |
else { | |
$existing[] = $alias['alias'] . ' (' . $alias['langcode'] . ')'; | |
} | |
} | |
// Return a message about existing aliases. This is not necessarily a problem, | |
// so we do not throw an exception. | |
if (!empty($existing)) { | |
return t('Aliases %aliases were not imported because they already exist.', ['%aliases' => implode(', ', $existing)]); | |
} | |
} | |
/** | |
* Helper function to save a path alias to the database. Copied from | |
* AliasStorage::save() and slightly modified. | |
*/ | |
function mymodule_add_path_alias($source, $alias, $langcode, $pid) { | |
if ($source[0] !== '/') { | |
throw new \InvalidArgumentException(sprintf('Source path %s has to start with a slash.', $source)); | |
} | |
if ($alias[0] !== '/') { | |
throw new \InvalidArgumentException(sprintf('Alias path %s has to start with a slash.', $alias)); | |
} | |
$fields = array( | |
'source' => $source, | |
'alias' => $alias, | |
'langcode' => $langcode, | |
); | |
// Insert or update the alias. | |
if (empty($pid)) { | |
$try_again = FALSE; | |
try { | |
$query = Database::getConnection()->insert('url_alias') | |
->fields($fields); | |
$pid = $query->execute(); | |
} | |
catch (\Exception $e) { | |
// If there was an exception, try to create the table. | |
if (!$try_again = $this->ensureTableExists()) { | |
// If the exception happened for other reason than the missing table, | |
// propagate the exception. | |
throw $e; | |
} | |
} | |
// Now that the table has been created, try again if necessary. | |
if ($try_again) { | |
$query = Database::getConnection()->insert('url_alias') | |
->fields($fields); | |
$pid = $query->execute(); | |
} | |
$fields['pid'] = $pid; | |
$operation = 'insert'; | |
} | |
else { | |
// Fetch the current values so that an update hook can identify what | |
// exactly changed. | |
try { | |
$original = Database::getConnection()->query('SELECT source, alias, langcode FROM {url_alias} WHERE pid = :pid', array(':pid' => $pid)) | |
->fetchAssoc(); | |
} | |
catch (\Exception $e) { | |
$this->catchException($e); | |
$original = FALSE; | |
} | |
$fields['pid'] = $pid; | |
$query = Database::getConnection()->update('url_alias') | |
->fields($fields) | |
->condition('pid', $pid); | |
$pid = $query->execute(); | |
$fields['original'] = $original; | |
$operation = 'update'; | |
} | |
if ($pid) { | |
// Do not clear cache or invoke hooks unlike the code in AliasStorage::save(). | |
return $fields; | |
} | |
return FALSE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment