Rose debug info
---------------

Позднее Ctrl + ↑

Книга Клэр Норт «Пятнадцать жизней Гарри Огаста»

Изначально я искал книги про день сурка, путешествие во времени и вот это всё, а нашёл её. И с таким сюжетом я прежде не сталкивался. Книга про жизнь сурка.

Главный герой — Гарри Огаст. Человек, у которого есть способность перерождаться после смерти снова и снова. С одним только «но» — он рождается в то же время, в том же месте, и проживает одну и ту же жизнь. Кроме этого, он помнит все свои предыдущие жизни, чем активно пользуется по ходу сюжета.

Сам сюжет крутится вокруг клуба «Хронос» — «хранителей» истории и/или времени; борьбы между теми, кто хочет сохранить историю и теми, кто хочет её переписать; скорого конца света.

Гарри Огаст

Гарри был особенным — мнемоником. Человеком, который помнил события предыдущих жизней во всех подробностях. В то время как у других подобных ему людей, со временем, воспоминания стирались.

Родился в Англии, в первый день 1919 года. Он был внебрачным ребёнком и жил в приёмной семье.

Прожив бесцельно первую жизнь, как обычный смертный, во второй он покончил с собой в 7 лет. Причиной тому стало, что людям вроде него, память о прошлых жизнях начинает возвращаться в очень раннем возрасте. В итоге, он не выдержал, сошёл с ума и выбросился с третьего этажа.

Со временем, в следующих жизнях, Гарри, в попытках разобраться кто он, а позже и в желании помочь спасти мир, будет много учиться. Он будет и врачом, и учёным, и профессором, и журналистом, и криминальным авторитетом, и даже религиозным последователем.

Клуб «Хронос»

Это закрытое, тайное общество, в которое входят люди, имеющие способность к перерождению. Клуб остаётся в тени и не вмешивается в ход истории. Его участники скапливают богатсва, помогают себе подобным и организуют фонды для потомков.

Достоврено неизвестно, кто его основал, но почти наверняка он возник в древнем Вавилоне в 3000 году до нашей эры. Это известно, потому что основатели клуба, в память об этом событии, на протяжении веков строят обелиск в пустыне. На обелиске они пишут свои имена и часто оставляют послание следующим поколениям членов клуба

Однако, как ни парадаксально, возможно, его основал человек из 18 века.

Со временем, клуб стал разрастаться: его члены активно разыскивали других — тех, кто ещё ничего про себя не понял. За несколько циклов рождений и смертей, клуб не только разросся в численности, но и во времени — его члены обнаруживались и в 20 веке, и в средневековье, и в более глубоком прошлом.

Конец света

Главное правило клуба — не вмешиваться в ход истории. Но были и те, кто не мог устоять перед соблазном. Первый случай, который, в итоге, привёл к концу света, произошёл в 1642 году в Париже. Его вызвал скромный, непритязательный человек по имени Виктор Хенесс.

Виктор был летописцем и в течение нескольких жизней снабжал клуб достоверными историческими фактами. В какой-то момент он начал вести переписку с людьми, которые родились в более поздние эпохи.

«Вопрос, сформулированный, скажем, в 19 или в начале 20 века, передавался назад, в более раннее время, — от человека, который был ребёнком, например, в 1850 году, к тому, кто к этому времени успел состариться, но в 1780 году был ещё совсем мальчишкой. Тот, в свою очередь, передавал послание человеку, пребывавшему на склоне лет в 1710 году, и так далее — пока наконец член клуба, живший в одно время с Хенессом, не получал возможность задать вопрос лично ему»

Узнав о будущем, он, завоевав доверие французского короля, начал менять мир. Понимая, что времени у него не много, он начал искать последователей в клубе, которые могли бы продолжить его дело после смерти.

«Виктор, не имея более или менее ясных представлений о грядущем техническом прогрессе и его достижениях, породил процесс, который должен был изменить лицо планеты до неузнаваемости. В 1693 году испытательный пробег от Парижа до Версаля совершил первый поезд, движимый паровым локомотивом. В 1701 году бронированный военный корабль, стреляя из мощных орудий, всего за два часа уничтожил целый пиратский флот у берегов Алжира. В 1768 году Эдо подвергся атакам самолётов-бомбардировщиков»

Виктор не увидел, чем всё закончилось. Конец света наступил, когда 18 ноября 1937 года группа боевиков захватила пусковые установки шахтного базирования и запустила три ядерные ракеты, вызвав серию ответных ударов. Затем последовала ядерная зима. К 1953 году жизнь на планете Земля прекратилась.

А потом всё началось сначала.

Другие детали сюжета

  1. Случай с Виктором — не единичный. В 20 веке всё обстояло много хуже: тот, кто активно менял ход истории, начал истреблять участников клуба, чтобы никто не смог его остановить. В итоге, внутри клуба, началась «гражданская» война. В цепи этих событий, Гарри был ключевым звеном, чтобы попытаться спасти мир.
  1. Формально, есть три вида смерти: смерть и перерождение, забвение и смерть без перерождения (то есть — окончательная).
  • Забвение — это стирание памяти. Фактически, это осознанное умертвление сознания: в следующей жизни — полное беспамятство, «чистый» лист.
  • Смерть без перерождения — это убийство в чистом виде. Убийца узнаёт дату и место рождения жертвы, находит мать и убивает её, — либо до беременности, либо во время. Это значит, что убийца может быть только членом клуба «Хронос».
  1. У Гарри было три весомых преимущества: будучи мнемоником, на него не действовала процедура забвения; так как он жил в приёмной семье, шансы на то, чтобы вычислить его происхождение и убить — были невелики.
  1. Финал — открытый. В конце Гарри умирает, но не окончательно. А значит, родится заново. В шестнадцатой жизни.

Открытые вопросы

  1. Даже если Виктор и нашёл последователей, то после смерти он всё равно рождается заново. Выходит, что конец света был уже в другой реальности, в другой временной линии.
  1. И получается, что каждое новое перерождение любого из участников клуба — это тоже создание новой реальности. Но парадокс в том, что эти реальности связаны между собой — потому что участники клуба помнят друг друга и связаны общей историей.
  1. Каждому из участников клуба отведён свой временной промежуток. Возникает вопрос: как появляются потомки? Ведь после смерти, всё начинается сначала. Значит, они появляются независимо от этого. А это значит, что они появляются на свет уже в другой реальности.
  1. Главная мысль в том, что эти реальности связаны между собой, но при этом они параллельны, и при этом независимы от «общей» истории — потому что время не перезапускается после смерти, а течёт дальше. Тем самым создавая новую реальность, которая всё равно связана с другими. Тем самым, можно подумать, что все реальности существуют одновременно и параллельно: и в прошлом, и в будущем, и в настоящем.

В заключении

Книгу прочитал за один присест. Мне, в целом, настолько понравилось, что я впервые решил написать об этом. Она стоит того, чтобы прочитать её целиком. Но, много фантазируя и пытаясь разобраться в деталях, можно голову сломать…

Привычка месяца: ежедневная медитация

Медитация появилась в моей жизни около четырёх лет назад. Но я никогда не медитировал регулярно и, в среднем, не больше 5—8 минут.

В апреле этого года у меня появились запросы: сбился режим сна, начал страдать бессоницей, переживал рабочие стрессы и подпустил эмоциональное выгорание (2.0). И вот, одна из полезных привычек, которую я захотел развить для преодоления этих недругов, — регулярная медитация.

Изначально, я просто сидел в тишине и концентрировался на дыхании. Затем пытался разнообразить практику фоновым шумом, мантрами, философскими текстами для размышлений. Но не то всё это — не подходило.

Месяц назад я наткнулся на приложение «Медитопия». И понеслась.

Что за приложение

Медитопия — это приложение для медитации. В нём есть аудиопрограммы, медитативные фоновые шумы, музыка, музыка для сна, истории на ночь.

Аудиоупрограмм — много: есть программы для начинающих, для улучшения сна, снятия стресса, тревожности, для работы с самооценкой, мотивацией и пр.

Приложение собирает всю статистику: число сеансов (медитаций), время и продолжительность по дням.

В приложении можно вести что-то вроде дневника эмоций и ощущений.

Можно скачать и в Гугл Плее, и в Апсторе.

Что изменилось

  1. Избавился от бессоницы и стал хорошо спать.
  1. Научился засыпать под музыку. Отрубает практически мгновенно (по моим меркам).
  1. Стал медитировать по 10—20 минут за сессию.
  1. Стал наблюдательнее: начал обращать внимание на звуки, цвета, детали, на которые прежде не обращал внимания.
  1. Научился чувствовать любую часть тела или всё тело целиком. Начал осознавать и ощущать прикосновения к чему-либо.
  1. Научился работать с тревожностью: абстрагироваться от негативных мыслей, смотреть на них со стороны и отпускать.
  1. Научился осозновать свои эмоциональные вспышки.
  1. Медитация вошла в привычку.

Как я веду аудиодневник

Я два года вёл текстовый дневник, но проблема в том, что писал я всё меньше, а мыслей и запросов становилось всё больше. Да и писать стало утомительнее.

В тот момент, в дневнике, я уже активно практиковал рубрику «рссс» (разговор с самим собой), а затем решил полностью перейти на этот формат.

Попробую тезисно описать процесс и штыки, с которыми сталкиваюсь.

  1. Не стал усложнять и начал пользоваться обычным системным диктофоном. Главное, что он умеет сохранять файлы в хронологическом порядке и синхронизироваться с облаком. Большего и не нужно.
  1. Суть аудиодневника такая же, как и у текстового: вываливать всё, что накопилось. Но есть штыки, особенно по началу. Некий барьер, неловкость или даже стеснение произносить вслух то, что крутится на уме.
  1. Важно этот барьер преодолеть, иначе не искренне получается: сказал не то, что думал на самом деле. Мои первые записи были верхом политкорректности со сглаженными углами. Со временем я привык и слышать, и слушать себя. И говорить как есть.
  1. В аудиодневнике те же проблемы, что и в текстовом: желание перезаписывать сказанное, не сохранять или удалять уже существующие записи. Кроме этого, добавляется недовольство своим голосом, произношением, запутанностью речи, долгими паузами между мыслями. Я научился принимать всё, как есть. Да и с каждым разом получается всё лучше.
  1. Ведя аудиодневник, эмоции ощущаются намного ярче, чем в текстовом виде. Хотя большинство записей я стараюсь записывать в нейтральном, спокойном тоне.
  1. Стараюсь соблюдать формат «одна запись — одна тема». Если чувствую, что захожу на территорию другой темы, говорю, что продолжение в следующей записи — и начинаю новую.
  1. Практикую и рубрики. Например, запись-наблюдение или идея.
  1. Продолжительность не имеет значения. У меня есть записи, которые длятся и 15 минут, и 15 секунд. Ограничений — нет.
  1. Помимо обсуждений, глубоких размышлений и вот этого всего, я записываю и скороговорки, и стихи, и вообще всё, что придёт на ум.
  1. По началу, записи я называл в формате «дата, время, номер записи». Сейчас — «дата, время, тема».
  1. Для меня один из плюсов аудиодневника в том, что записи можно делать во время прогулки, например.
  1. А один из минусов — записи можно делать не всегда и не везде. Процесс требует уединения.

См. также заметки о том, как я веду текстовый дневник и видеодневник.

Про конспекты

Обычно, чтобы законспектировать книгу, я её читаю, затем ещё раз перечитываю и затем в несколько подходов пишу сам конспект.

Прежде я думал, что если не дочитаю книгу до конца и напишу конспект — это будет слишком низко с моей стороны и недостойно публикации. Но вдруг меня осенило: я же пишу для себя. Конспект — это про то, что на меня больше всего повлияло.

Теперь барьеров нет. Я буду писать, даже если не прочитал и двадцати страниц, но в моей голове уже успело что-то щёлкнуть. Это же касается и всего остального.

 388   2020   конспект

Эгея: как добавить кнопку подписки на телеграм

  1. Переходим в блог/themes/тема/template/
  1. Создаём файл subscribe.tmpl.php
  1. Вставляем код:
<div class="telegramus--with-margin">
   <a class="telegramus" href="tg://resolve?domain=antonkim_channel">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M6,11.960784l-1,-3l11,-8l-15.378,5.914c0,0 -0.672,0.23 -0.619,0.655c0.053,0.425 0.602,0.619 0.602,0.619l3.575,1.203l1.62,5.154l2.742,-2.411l-0.007,-0.005l3.607,2.766c0.973,0.425 1.327,-0.46 1.327,-0.46l2.531,-13.435l-10,11zz"></path></svg>
      Подписаться на новые статьи
   </a>
</div>

5. Заменяем antonkim_channel на свой вариант.

6. Затем, в той же папке, открываем layout.tmpl.php и находим вот это (55 строка):

<div class="content">

<?php _T ('heading') ?>
<?php _T ('theme-preview') ?>
<?php _T ('message') ?>
<?php _T ('welcome') ?>
<?php _T ('drafts') ?>
<?php _T ('notes') ?>
<?php _T ('notes-list') ?>
<?php _T ('tags') ?>
<?php _T ('nothing') ?>
<?php _T ('sessions') ?>
<?php _T ('pages') ?>
<?php _T ('comments') ?>
<?php _T ('popular') ?>
<?php _T ('tags-menu') ?>
<?php _T ('unsubscribe') ?>
<?php _T ('form') ?>

</div>
  1. Между sessions и pages вставляем:
<?php _T ('subscribe') ?>
  1. Открываем стили блог/themes/тема/styles/main.css
  1. В самом конце (или где душе угодно) вставляем:
.telegramus--with-margin {
    margin: 0 0 40px;
}

a:link.telegramus,
a:visited.telegramus {
    font-size: 100%;
    display: inline-block;
    padding: 8px 10px 10px;
    transition: .1s all ease-in-out;
    color: #000;
    border: 1px solid rgba(0, 0, 0, .3);
    border-radius: 6px;
}

a:hover.telegramus {
    color: #e20016;
    border-color: rgba(226, 0, 22, .5);
}

a:hover.telegramus img {
    opacity: .9;
}

.telegramus img {
    position: relative;
    top: 3px;
    height: 20px;
    margin-right: 8px;
}

.telegramus svg {
    width: 30px;
    height: 22px;
    vertical-align: middle;
    margin-top: -3px;
    stroke: none;
}
  1. Готово.
  1. Добавив кнопку, вы столкнётесь с тем, что будете видеть её, например, при добавлении заметки. Это может раздражать. Чтобы её не видеть, в файле subscibe.tmpl.php, в самом верху, вставьте код:
<?php if ($content['sign-in']['done?']) { } 
  else { ?>
  1. И в самом низу закройте:
<?php } ?>
  1. Теперь, когда вы будете залогинены, кнопку будут видеть все — кроме вас.
  2. Готово — 2.

OpenCart: как минифицировать HTML

Для более быстрой загрузки страниц.

Что делать

  1. Открываем сайт/system/library/response.php
  1. Находим код (~108 строка):
public function output() {
	if ($this->output) {
		$output = $this->level ? $this->compress($this->output, $this->level) : $this->output;
		
		if (!headers_sent()) {
			foreach ($this->headers as $header) {
				header($header, true);
			}
		}
		
		echo $output;
	}
}
  1. Заменяем на:
public function output() {
 
if ($this->output) {
    $this->output = preg_replace("/(\n)+/", "\n", $this->output);
    $this->output = preg_replace("/\r\n+/", "\n", $this->output);
    $this->output = preg_replace("/\n(\t)+/", "\n", $this->output);
    $this->output = preg_replace("/\n(\ )+/", "\n", $this->output);
    $this->output = preg_replace("/\>(\n)+</", '><', $this->output);
    $this->output = preg_replace("/\>\r\n</", '><', $this->output);
}

if ($this->output) {
	$output = $this->level ? $this->compress($this->output, $this->level) : $this->output;
	
	if (!headers_sent()) {
		foreach ($this->headers as $header) {
			header($header, true);
		}
	}
	
	echo $output;
}
}
  1. Сохраняем, обновляем кэш.
  1. Готово.
 1288   2020   OpenCart 3   работа

OpenCart: как сделать сортировку атрибутов по порядку сортировки

Потратил кучу времени на поиски решения, а оно оказалось до смешного простым.

В чём проблема

Вот мы создали группу атрибутов. Затем создали атрибуты, привязали к группе атрибутов, задали порядок сортировки. На сайте всё отображается нормально — согласно порядку сортировки. В админке же — всё сортируется по названиям, и это очень сбивает.

Что делать

  1. Открываем сайт/admin/model/catalog/attribute.php.
  1. Находим код (~53 строка):
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
	$sql .= " ORDER BY " . $data['sort'];
} else {
	$sql .= " ORDER BY attribute_group, ad.name";
}
  1. Изменяем последнюю строку:
$sql .= " ORDER BY attribute_group, a.sort_order, ad.name";
  1. То есть, по умолчанию, в карточке товара в админке, стоит сортировка по названию. Мы же сделали по порядку сортировки, а затем по названию.
  1. Сохраняем, обновляем кэш.
  1. Готово.
 1656   2020   OpenCart 3   работа

Эгея: как добавить аналитику

Без учёта своего присутствия.

Первый способ

  1. Переходим в блог/themes/тема/templates/
  1. Создаём файл analytics.tmpl.php
  1. Вставляем код:
<?php if ($content['sign-in']['done?']) { } 
  else { ?>

<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
   (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
   m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
   (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");

   ym(123456789, "init", {
        clickmap:true,
        trackLinks:true,
        accurateTrackBounce:true,
        webvisor:true
   });
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/123456789" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->

<?php } ?>
  1. Заменяем код Яндекса на свой.
  1. Затем, в той же папке, открываем layout.tmpl.php и в самом конце вставляем:
<?php _T ('analytics'); ?>
  1. Готово. Теперь, когда вы залогигены, будут учитываться все визиты — кроме вашего.

Второй способ

  1. Переходим в блог/user/extras/
  1. Создаём файл footer-post.tmpl.php
  1. Вставляем код аналитики.
  1. Готово.

В чём разница

В первом случае — всё будет храниться в папке темы, а не разрознено. Такой способ можно использовать и для других целей.

Во втором случае — используется встроенный блок Эгеи.

OpenCart: автогеренация тайтла

Чтобы получилось вот так:

При этом, чтобы иметь возможность отдельно редактировать сам тайтл.

Что делать

  1. Открываем сайт/admin/view/template/catalog/product_form.twig
  1. Находим код (~67 строка):
<input type="text" name="product_description[{{ language.language_id }}][meta_title]" value="{{ product_description[language.language_id] ? product_description[language.language_id].meta_title }}" placeholder="{{ entry_meta_title }}" id="input-meta-title{{ language.language_id }}" class="form-control" />
  1. После него вставляем:
<script type="text/javascript">
$(function() {
  var $name_input = $("input[name='product_description[{{ language.language_id }}][name]']");
  var $meta_title = $("input[name='product_description[{{ language.language_id }}][meta_title]']");

  $name_input.keyup(function() {
  $meta_title.val($name_input.val());
  });
});
</script>
  1. Сохраняем, обновляем кэш.
  1. Готово.
  1. Можно пойти дальше. Например, чтобы после названия автоматически генерировалось «купить в „магазине“».
  1. Изменяем одну строку:
$meta_title.val($name_input.val() + 'Тут какой-то текст');
  1. Готово — 2.

Ту же самую процедуру можно провернуть и с категориями.

Спасибо за помощь Ярославу Усенко.

 635   2020   OpenCart 3   работа

OpenCart: как сделать сортировку товаров по наличию

И в магазине, и в админке.

В чём проблема

По умолчанию, все товары в категориях, страницах производителей, поиске — сортируются по названиям в алфавитном порядке. И даже те товары, которых нет в наличии, могут отображаться в начале списка. А когда таких товаров много — это становится проблемой.

Что делать

  1. Открываем сайт/catalog/model/catalog/product.php
  1. Находим код (~168 строка):
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
	if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
		$sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
	} elseif ($data['sort'] == 'p.price') {
		$sql .= " ORDER BY (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
	} else {
		$sql .= " ORDER BY " . $data['sort'];
	}
} else {
	$sql .= " ORDER BY p.sort_order";
}
  1. Заменяем его на:
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
    if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
        $sql .= " ORDER BY p.stock_status_id DESC, LCASE(" . $data['sort'] . ")";
    } elseif ($data['sort'] == 'p.price') {
        $sql .= " ORDER BY p.stock_status_id DESC, (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
    } else {
        $sql .= " ORDER BY p.stock_status_id DESC, " . $data['sort'];
    }
} else {
    $sql .= " ORDER BY p.stock_status_id DESC, p.sort_order";
}
  1. Сохраняем, обновляем кэш.
  1. Готово. Товары будут сортироваться по наличию. Товаров, которых нет в наличии, будут отображаться в конце списка.
  1. Можно сортировать и по количеству, а уже затем по наличию. Для этого заменяем на:
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
    if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
        $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, LCASE(" . $data['sort'] . ")";
    } elseif ($data['sort'] == 'p.price') {
        $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, (CASE WHEN special IS NOT NULL THEN special WHEN discount IS NOT NULL THEN discount ELSE p.price END)";
    } else {
        $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, " . $data['sort'];
    }
} else {
    $sql .= " ORDER BY p.quantity DESC, p.stock_status_id DESC, p.sort_order";
}
  1. Можно использовать разные комбинации: сортировать по стоимости, рейтингу, дате добавления. Нужно лишь подменить значения в коде выше. Вот они:
$sort_data = array(
    'pd.name',
    'p.model',
    'p.quantity',
    'p.price',
    'rating',
    'p.sort_order',
    'p.date_added'
);

Как сделать в админке

  1. Открываем сайт/admin/model/catalog/product.php.
  1. Делаем тоже самое, что и наверху.
  1. Готово.

По теме

Сортировка данных в SQL (ORDER BY).

 1713   2020   OpenCart 3   работа
Ранее Ctrl + ↓