| 
<?phpdeclare(strict_types=1);
 
 use Airship\Engine\{
 View,
 State
 };
 
 /**
 * @global View $lens
 * @global array $_settings
 * @global array $active
 * @global State $state
 *
 * Load this in index.php, or anywhere /AFTER/ the CABIN_DIR constant exists
 */
 if (\defined('CABIN_DIR')) {
 $motifCacheFile = ROOT . '/tmp/cache/' . CABIN_NAME . '.motifs.json';
 if (\file_exists($motifCacheFile) && \filesize($motifCacheFile) > 0) {
 // Load from this cabin's motif cache.
 $motifs = \Airship\loadJSON($motifCacheFile);
 $state->motifs = $motifs;
 } else {
 // Let's make sure our directories exist:
 if (!\is_dir(CABIN_DIR . '/View/motif')) {
 \mkdir(CABIN_DIR . '/View/motif', 0775);
 } else {
 @\chmod(CABIN_DIR . '/View/motif', 0775);
 }
 if (!\is_dir(CABIN_DIR . '/public/motif')) {
 \mkdir(CABIN_DIR . '/public/motif', 0775);
 } else {
 @\chmod(CABIN_DIR . '/public/motif', 0775);
 }
 
 // Parse the Cabin's Motifs configuration file:
 $motifsJSONFile = ROOT . '/Cabin/' . CABIN_NAME . '/config/motifs.json';
 if (\is_dir(CABIN_DIR . '/View/motif') && \is_readable($motifsJSONFile)) {
 $motifs = [];
 $motifsJSONData = \Airship\loadJSON($motifsJSONFile);
 
 // Parse a particular motif:
 foreach ($motifsJSONData as $motif => $motifConfig) {
 if (empty($motifConfig['enabled'])) {
 continue;
 }
 if (isset($motifConfig['path'])) {
 $motifStart = CABIN_DIR . '/View/motif/' . $motif;
 $motifEnd = ROOT . '/Motifs/' . $motifConfig['path'];
 
 // If the Motif is malicious, alert.
 if (\strpos($motifStart, CABIN_DIR . '/View/motif') === false) {
 $state->logger->alert(
 'Potential directory traversal in Motif config.',
 [
 'cabin' => $active['name'],
 'motif' => $motif,
 'path' => $motifStart
 ]
 );
 
 // SKIP! We have a potential directory traversal
 continue;
 }
 if (\strpos($motifEnd, ROOT . '/Motifs') === false) {
 $state->logger->alert(
 'Potential directory traversal in Motif config.',
 [
 'cabin' => $active['name'],
 'motif' => $motif,
 'path' => $motifEnd
 ]
 );
 
 // SKIP! We have a potential directory traversal
 continue;
 }
 
 // Create the necessary symlinks if they do not already exist:
 if (!\is_link($motifStart)) {
 \symlink($motifEnd . '/lens', $motifStart);
 }
 if (\is_dir($motifEnd . '/public')) {
 $motifPublic = CABIN_DIR . '/public/motif/' . $motif;
 if (!\is_link($motifPublic)) {
 \symlink($motifEnd . '/public', $motifPublic);
 }
 }
 
 // Finally, load the configuration:
 if (\file_exists($motifEnd . '/motif.json')) {
 $motifConfig['config'] = \Airship\loadJSON($motifEnd . '/motif.json');
 } else {
 $motifConfig['config'] = [];
 }
 
 $motifs[$motif] = $motifConfig;
 }
 }
 \Airship\saveJSON($motifCacheFile, $motifs);
 $state->motifs = $motifs;
 } else {
 die(\__("FATAL ERROR: Motifs file is not readable"));
 }
 }
 }
 
 $userMotif = \Airship\ViewFunctions\user_motif();
 if (!empty($userMotif)) {
 $activeMotif = $userMotif['name'];
 } elseif (isset($_settings['active-motif'])) {
 $activeMotif = $_settings['active-motif'];
 }
 if (isset($activeMotif)) {
 $lens
 ->setBaseTemplate($activeMotif)
 ->loadMotifCargo($activeMotif)
 ->loadMotifConfig($activeMotif)
 ->addGlobal('MOTIF', $state->motif_config);
 }
 
 |