werk21 blog - The www.werk21.de team blogs on technical and other issues. https://blog.werk21.de/en en How to "fix" 403 access denied exceptions for Drupal 8 Views translation routes https://blog.werk21.de/en/2018/12/06/how-fix-403-access-denied-exceptions-drupal-8-views-translation-routes <span>How to &quot;fix&quot; 403 access denied exceptions for Drupal 8 Views translation routes</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Thu, 12/06/2018 - 08:50</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Today I worked on a project where the customer had asked us to add a missing translation for the label of an exposed filter of a view. The view configuration was originally imported upon installation of a contributed module, that uses that view. I thought that this would be an easy task quickly done: We have configuration translation enabled on that system so all views have a "Translate" operation that you can use to translate the view. Not in this case, of course ;).<br /> <br /> I was logged in as the magic super user 1 with the magic administrator role assigned to it, but I still got a 403 access denied exception each time I tried to translate this particular view. Other views that we had created manually or that were provided by other contribued modules worked fine. But not this one. What the ****?<br /> <br /> After searching the core issue queue for a while to no avail, I ended up to comment out the "throw AccessDeniedException" in the AccessAwareRouter, just out of curiosity. After all this was a dev system, so what could possibly go wrong? And then I instantly realized what the problem was. The list of translations was displayed and I saw that the "original translation" was "language undefined" or "und". Looking at the configuration object more closely confirmed, that the language was "und". In hindsight, it was kind of logical that I couldn't translate that one, right?<br /> <br /> Of course I didn't make the foolish attempt to create an English translation for the view via UI. Since Views doesn't have a UI to change the language of a view like for example Content entities have, I decided to just export the configuration using Drush, find the YAML file for the configuration object in question, edit it so that the language was no longer "und", but "en", and import the configuration again using Drush. Now I was able to translate the view using the UI without my quick modification of the AccessAwareRouter.<br /> <br /> Yet another lesson learned.</p></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/drush" class="label label-default" hreflang="de">drush</a> <a href="/de/tags/views" class="label label-default" hreflang="de">Views</a> <a href="/en/tags/translation" class="label label-default" hreflang="en">Translation</a> <a href="/en/tags/config-translation" class="label label-default" hreflang="en">Config Translation</a> <a href="/en/tags/yml" class="label label-default" hreflang="en">yml</a> <a href="/en/tags/accessawarerouter" class="label label-default" hreflang="en">AccessAwareRouter</a> <a href="/en/tags/accessdeniedexception" class="label label-default" hreflang="en">AccessDeniedException</a> <a href="/en/tags/exception" class="label label-default" hreflang="en">Exception</a> </div> Thu, 06 Dec 2018 07:50:41 +0000 patrick 148 at https://blog.werk21.de Open multiple key database files upon KeePass2 startup https://blog.werk21.de/en/2018/09/24/open-multiple-key-database-files-upon-keepass2-startup <span>Open multiple key database files upon KeePass2 startup</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Mon, 09/24/2018 - 08:19</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p><a href="https://keepass.info/">KeePass2</a> has a setting to open the most recently opened key database upon start-up, but what if you want to open multiple key database files? One way to do this is to add a trigger that will open the files on start-up.</p> <ol> <li>Go to <em>Tools</em> &gt; <em>Options</em> &gt; <em>Advanced</em> and make sure that <em>Remember and automatically open last used database on startup</em> is unchecked.</li> <li>Go to <em>Tools</em> &gt; <em>Triggers</em> and click on the <em>Add</em> button.</li> <li>On the <em>Properties</em> tab, specify a convenient name to your liking.</li> <li>On the <em>Events</em> tab, click the <em>Add</em> button and add an <em>Application started and ready</em> event.</li> <li>On the <em>Actions</em> tab, cklick the <em>Add</em> button and add an <em>Open database file</em> action. As <em>File/URL</em> setting, specify the full path to your key database file. If you use a password to open your database, it is suggested to leave the <em>Password</em> setting empty as it will be stored in unencrypted form. You will then be prompted to enter the password upon start-up as usual.</li> <li>Add additional <em>Open database file</em> actions for each database you want to open.</li> </ol></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systeme/pc" class="label label-default" hreflang="de">PC</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/en/tags/keepass2" class="label label-default" hreflang="en">KeePass2</a> </div> Mon, 24 Sep 2018 06:19:16 +0000 patrick 145 at https://blog.werk21.de Build xen-hypervisor 4.10 / 4.11 and xen-tools on Ubuntu 16.04 or 18.04 for PVH https://blog.werk21.de/en/2018/02/08/build-xen-hypervisor-410-411-and-xen-tools-ubuntu-1604-or-1804-pvh <span>Build xen-hypervisor 4.10 / 4.11 and xen-tools on Ubuntu 16.04 or 18.04 for PVH</span> <span><span lang="" about="/en/user/15" typeof="schema:Person" property="schema:name" datatype="">kelly</span></span> <span>Thu, 02/08/2018 - 15:05</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Ubuntu 16.04 comes with xen-hypervisor 4.6, the next LTS-version <a href="https://packages.ubuntu.com/bionic/xen-system-amd64">Ubuntu 18.04 ships xen 4.9</a>. Updates for meltdown ("Xen PTI") will be published for versions 4.6 and newer, but PVH will only published for xen 4.8 and 4.10. <a href="https://xenbits.xen.org/xsa/advisory-254.html">See XSA-254</a>.</p> <p>To protect your system with <a href="https://wiki.xen.org/wiki/Xen_Project_Software_Overview#PVH_.28x86.29">PVH</a> against meltdown you have to build your xen-hypervisor from source.</p> <p>This howto based on this <a href="https://wiki.xenproject.org/wiki/Compiling_Xen_From_Source">official howto</a>.</p> <h2>Xen-Hypervisor</h2> <h3>Install requirements for build</h3> <p>Your Ubuntu must run with HWE-Kernel (linux-generic-hwe-16.04) for Linux 4.11 or newer kernel.</p> <h4>For Ubuntu 16.04:</h4> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">apt<span style="color: #339933;">-</span>get install build<span style="color: #339933;">-</span>essential apt<span style="color: #339933;">-</span>get install bcc bin86 gawk bridge<span style="color: #339933;">-</span>utils iproute libcurl3 libcurl4<span style="color: #339933;">-</span>openssl<span style="color: #339933;">-</span>dev bzip2 module<span style="color: #339933;">-</span>init<span style="color: #339933;">-</span>tools transfig tgif  apt<span style="color: #339933;">-</span>get install texinfo texlive<span style="color: #339933;">-</span>latex<span style="color: #339933;">-</span>base texlive<span style="color: #339933;">-</span>latex<span style="color: #339933;">-</span>recommended texlive<span style="color: #339933;">-</span>fonts<span style="color: #339933;">-</span>extra texlive<span style="color: #339933;">-</span>fonts<span style="color: #339933;">-</span>recommended pciutils<span style="color: #339933;">-</span>dev mercurial apt<span style="color: #339933;">-</span>get install make gcc libc6<span style="color: #339933;">-</span>dev zlib1g<span style="color: #339933;">-</span>dev python python<span style="color: #339933;">-</span>dev python<span style="color: #339933;">-</span>twisted libncurses5<span style="color: #339933;">-</span>dev patch libvncserver<span style="color: #339933;">-</span>dev libsdl<span style="color: #339933;">-</span>dev libjpeg<span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install libnl<span style="color: #339933;">-</span>route<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">200</span> libnl<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev libnl<span style="color: #339933;">-</span>cli<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev libnl<span style="color: #339933;">-</span>genl<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev libnl<span style="color: #339933;">-</span>route<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install iasl libbz2<span style="color: #339933;">-</span>dev e2fslibs<span style="color: #339933;">-</span>dev git<span style="color: #339933;">-</span>core uuid<span style="color: #339933;">-</span>dev ocaml ocaml<span style="color: #339933;">-</span>findlib libx11<span style="color: #339933;">-</span>dev bison flex xz<span style="color: #339933;">-</span>utils libyajl<span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install <a href="http://www.php.net/gettext"><span style="color: #990000;">gettext</span></a> libpixman<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">-</span>dev libaio<span style="color: #339933;">-</span>dev markdown pandoc &nbsp; apt<span style="color: #339933;">-</span>get install libc6<span style="color: #339933;">-</span>dev<span style="color: #339933;">-</span>i386 apt<span style="color: #339933;">-</span>get install lzma lzma<span style="color: #339933;">-</span>dev liblzma<span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install libsystemd<span style="color: #339933;">-</span>dev</pre></div> <h4>For Ubuntu 18.04:</h4> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">apt<span style="color: #339933;">-</span>get install build<span style="color: #339933;">-</span>essential apt<span style="color: #339933;">-</span>get install bcc bin86 gawk bridge<span style="color: #339933;">-</span>utils iproute2 libcurl4 libcurl4<span style="color: #339933;">-</span>openssl<span style="color: #339933;">-</span>dev bzip2 module<span style="color: #339933;">-</span>init<span style="color: #339933;">-</span>tools transfig tgif apt<span style="color: #339933;">-</span>get install texinfo texlive<span style="color: #339933;">-</span>latex<span style="color: #339933;">-</span>base texlive<span style="color: #339933;">-</span>latex<span style="color: #339933;">-</span>recommended texlive<span style="color: #339933;">-</span>fonts<span style="color: #339933;">-</span>extra texlive<span style="color: #339933;">-</span>fonts<span style="color: #339933;">-</span>recommended pciutils<span style="color: #339933;">-</span>dev mercurial apt<span style="color: #339933;">-</span>get install make gcc libc6<span style="color: #339933;">-</span>dev zlib1g<span style="color: #339933;">-</span>dev python python<span style="color: #339933;">-</span>dev python<span style="color: #339933;">-</span>twisted libncurses5<span style="color: #339933;">-</span>dev patch libvncserver<span style="color: #339933;">-</span>dev libsdl<span style="color: #339933;">-</span>dev libjpeg<span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install libnl<span style="color: #339933;">-</span>route<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">200</span> libnl<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev libnl<span style="color: #339933;">-</span>cli<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev libnl<span style="color: #339933;">-</span>genl<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev libnl<span style="color: #339933;">-</span>route<span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install iasl libbz2<span style="color: #339933;">-</span>dev e2fslibs<span style="color: #339933;">-</span>dev git<span style="color: #339933;">-</span>core uuid<span style="color: #339933;">-</span>dev ocaml ocaml<span style="color: #339933;">-</span>findlib libx11<span style="color: #339933;">-</span>dev bison flex xz<span style="color: #339933;">-</span>utils libyajl<span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install <a href="http://www.php.net/gettext"><span style="color: #990000;">gettext</span></a> libpixman<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">-</span>dev libaio<span style="color: #339933;">-</span>dev markdown pandoc &nbsp; apt<span style="color: #339933;">-</span>get install libc6<span style="color: #339933;">-</span>dev<span style="color: #339933;">-</span>i386 apt<span style="color: #339933;">-</span>get install lzma lzma<span style="color: #339933;">-</span>dev liblzma<span style="color: #339933;">-</span>dev apt<span style="color: #339933;">-</span>get install libsystemd<span style="color: #339933;">-</span>dev</pre></div> <h3>Download and prepare and make</h3> <h4>Ubuntu 16.04</h4> <p>We will use the stable version 4.10. xen-hypervisor 4.10 brings the new guest-type <a href="http://xenbits.xen.org/xsa/advisory-254.html">"pvh" baremetal</a>.</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">git clone git<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//xenbits.xen.org/xen.git</span> cd xen git checkout origin<span style="color: #339933;">/</span>stable<span style="color: #339933;">-</span><span style="color:#800080;">4.10</span></pre></div> <h4>Ubuntu 18.04</h4> <p>We will use stable version 4.11 due to a <a href="https://xenbits.xen.org/gitweb/?p=qemu-xen.git;a=commitdiff;h=5c3fdee026a204a59cb392e43a313ab558de9682;hp=a19f3519ed720f103b56dc2969993a60e76ee3f1">bug to qemu-xen and newer libc</a> - in a few days this commits will be available for stable-4.10 either (thanks to Anthony Perard for quick response - 2018-06-29).</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">git clone git<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//xenbits.xen.org/xen.git</span> cd xen git checkout origin<span style="color: #339933;">/</span>stable<span style="color: #339933;">-</span><span style="color:#800080;">4.11</span></pre></div> <h4>Configure and make</h4> <p>Ubuntu uses systemd:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #339933;">./</span>configure <span style="color: #339933;">--</span>enable<span style="color: #339933;">-</span>systemd</pre></div> <p>For first make use:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">make dist</pre></div> <p>For new make use <em>make world</em> (same like <em>make clean &amp;&amp; make dist</em>).</p> <p>Get a coffee now.</p> <h3>Install</h3> <p>The install-files are in /dist/install. And you will find an install-script in dist/install.sh. <strong>Dont use this script! It will breaks your /var/run-folder</strong>.</p> <p>You can copy the files via <em>cp -a</em> or <em>rsync </em>in your system. Or you may use <em>make debball </em>and install the package from file (I didnt try)<em>.</em></p> <h3>Post-Install</h3> <p>After copying the files you will do some changes in your system:</p> <h4>Reload dynamic libraries:</h4> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #339933;">/</span>sbin<span style="color: #339933;">/</span>ldconfig</pre></div> <h4>Grub-Settings:</h4> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><a href="http://www.php.net/mkdir"><span style="color: #990000;">mkdir</span></a> <span style="color: #339933;">-</span>p <span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span><span style="color: #b1b100;">default</span><span style="color: #339933;">/</span>grub<span style="color: #339933;">.</span>d</pre></div> <p>Create /etc/default/grub.d/xen.cfg:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">vi <span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span><span style="color: #b1b100;">default</span><span style="color: #339933;">/</span>grub<span style="color: #339933;">.</span>d<span style="color: #339933;">/</span>xen<span style="color: #339933;">.</span>cfg</pre></div> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">GRUB_DISABLE_OS_PROBER<span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">true</span> GRUB_CMDLINE_XEN_DEFAULT<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;dom0_mem=2560M,max:2560M&quot;</span> GRUB_DEFAULT<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Ubuntu GNU/Linux, mit Xen-Hypervisor&quot;</span></pre></div> <p>Be careful! The last settings depends on your system-language! For english use: "Ubuntu GNU/Linux, with Xen hypervisor" - Ubuntu 18.04 does not use the german translation!</p> <p>You have to update grub:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">update<span style="color: #339933;">-</span>grub</pre></div> <h4>Enable systemd-files:</h4> <p>In the current version is a bug and xendomains.service and /etc/init.d/xendomains are created both. To use systemd you have to remove /etc/init.d/xendomains</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">rm <span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span>init<span style="color: #339933;">.</span>d<span style="color: #339933;">/</span>xendomains</pre></div> <h4> </h4> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">systemctl enable xen<span style="color: #339933;">-</span>qemu<span style="color: #339933;">-</span>dom0<span style="color: #339933;">-</span>disk<span style="color: #339933;">-</span>backend<span style="color: #339933;">.</span>service systemctl enable xen<span style="color: #339933;">-</span>init<span style="color: #339933;">-</span>dom0<span style="color: #339933;">.</span>service systemctl enable xenconsoled<span style="color: #339933;">.</span>service systemctl enable xenstored<span style="color: #339933;">.</span>service systemctl enable xendomains<span style="color: #339933;">.</span>service</pre></div> <p>Optional you can enable xen-watchdog.service</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">systemctl enable xen<span style="color: #339933;">-</span>watchdog<span style="color: #339933;">.</span>service</pre></div> <h4>Configure xen</h4> <p>Configure xen for your needs.</p> <h2>xen-tools</h2> <p>For creating new VMs you can use xen-tools. Unfortunately you cannot use the ubuntu-package because it requires xen-hypervisor. So we build from source.</p> <h3>Install requirements for build</h3> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">apt install lvm2 debootstrap libconfig<span style="color: #339933;">-</span>inifiles<span style="color: #339933;">-</span>perl libdata<span style="color: #339933;">-</span>validate<span style="color: #339933;">-</span>domain<span style="color: #339933;">-</span>perl libdata<span style="color: #339933;">-</span>validate<span style="color: #339933;">-</span>ip<span style="color: #339933;">-</span>perl libdata<span style="color: #339933;">-</span>validate<span style="color: #339933;">-</span>uri<span style="color: #339933;">-</span>perl libfile<span style="color: #339933;">-</span>slurp<span style="color: #339933;">-</span>perl libfile<span style="color: #339933;">-</span>which<span style="color: #339933;">-</span>perl libsort<span style="color: #339933;">-</span>versions<span style="color: #339933;">-</span>perl libterm<span style="color: #339933;">-</span>ui<span style="color: #339933;">-</span>perl libtext<span style="color: #339933;">-</span>template<span style="color: #339933;">-</span>perl openssh<span style="color: #339933;">-</span>client perl debian<span style="color: #339933;">-</span>archive<span style="color: #339933;">-</span>keyring rinse libtest<span style="color: #339933;">-</span>notabs<span style="color: #339933;">-</span>perl</pre></div> <h3>Download and prepare and make</h3> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">git clone https<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//github.com/xen-tools/xen-tools.git</span> cd xen<span style="color: #339933;">-</span>tools make install</pre></div> <p>You can ignore the warning about loop-module because in Ubuntu 16.04 loop is compliled into the kernel and the default value for <em>max_loop</em> is 0 (see <em>/sys/module/loop/parameters/max_loop</em>).</p> <p>If you want only the install-files (e.g. for build you own package), you can edit the Makefile and manually set the variable <em>DESTDIR</em> before <em>make install</em>.</p> <h3>Configure xen-tools</h3> <p>Configure xen-tools for your needs.</p> <p> </p> <h2>Reboot</h2> <p>After reboot you have your Ubuntu 16.04 on xen-hypervisor 4.10.</p> <p>Test:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">xentop</pre></div> <h2>Settings for PVH</h2> <p>For PVH you have to use Linux 4.11 or newer (e.g. HWE-Kernel) in guest:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">apt install linux<span style="color: #339933;">-</span>virtual<span style="color: #339933;">-</span>hwe<span style="color: #339933;">-</span><span style="color:#800080;">16.04</span> linux<span style="color: #339933;">-</span>tools<span style="color: #339933;">-</span>virtual<span style="color: #339933;">-</span>hwe<span style="color: #339933;">-</span><span style="color:#800080;">16.04</span></pre></div> <p>Then you can use:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">bootloader <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/usr/local/bin/pygrub'</span> type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pvh&quot;</span></pre></div> <p>If you have an old kernel in your guest-system, you have to boot from dom0-kernel with this settings:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;pvh&quot;</span> kernel<span style="color: #339933;">=</span><span style="color: #0000ff;">'/vmlinuz'</span> ramdisk<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;/initrd.img&quot;</span></pre></div> <p> </p></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/server" class="label label-default" hreflang="de">Server</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/xen" class="label label-default" hreflang="de">xen</a> <a href="/de/tags/ubuntu" class="label label-default" hreflang="de">ubuntu</a> <a href="/en/tags/meltdown" class="label label-default" hreflang="en">Meltdown</a> </div> Thu, 08 Feb 2018 14:05:36 +0000 kelly 135 at https://blog.werk21.de Date (range) fields and Entity Query [Update] https://blog.werk21.de/en/2018/02/05/date-range-fields-and-entity-query-update <span>Date (range) fields and Entity Query [Update]</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Mon, 02/05/2018 - 08:09</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Ever wanted to add a <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21Query%21QueryInterface.php/function/QueryInterface%3A%3Acondition/8.4.x">condition</a> on the value of a date field on an <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/Drupal%3A%3AentityQuery/8.4.x">entity query</a> in Drupal 8? Here is how it works reliably.</p> <p>For Drupal 8.5.x and later:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> Drupal\Core\Datetime\DrupalDateTime<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">use</span> Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface<span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Get a date string suitable for use with entity query.</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DrupalDateTime<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTimezone</span><span style="color: #009900;">(</span><span style="color: #000000; font-weight: bold;">new</span> \DateTimeZone<span style="color: #009900;">(</span>DateTimeItemInterface<span style="color: #339933;">::</span><span style="color: #004000;">STORAGE_TIMEZONE</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #009900;">(</span>DateTimeItemInterface<span style="color: #339933;">::</span><span style="color: #004000;">DATETIME_STORAGE_FORMAT</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Set the condition.</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date.value'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$date</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&gt;'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span></pre></div> <p>For Drupal 8.4.x and earlier:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> Drupal\Core\Datetime\DrupalDateTime<span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Get a date string suitable for use with entity query.</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DrupalDateTime<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTimezone</span><span style="color: #009900;">(</span><span style="color: #000000; font-weight: bold;">new</span> \DateTimeZone<span style="color: #009900;">(</span>DATETIME_STORAGE_TIMEZONE<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #009900;">(</span>DATETIME_DATETIME_STORAGE_FORMAT<span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Set the condition.</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date.value'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$date</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&gt;'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span></pre></div> <p>The trick is to use a <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Datetime%21DrupalDateTime.php/class/DrupalDateTime/8.4.x">DrupalDateTime</a> object, on which we set the proper time zone used by the storage (provided by the constant <a href="https://api.drupal.org/api/drupal/core%21modules%21datetime%21datetime.module/constant/DATETIME_STORAGE_TIMEZONE/8.4.x"><span class="geshifilter"><code class="php geshifilter-php">DATETIME_STORAGE_TIMEZONE</code></span></a>) and format that in the proper date format used by the storage (provided by the constant <a href="https://api.drupal.org/api/drupal/core%21modules%21datetime%21datetime.module/constant/DATETIME_DATETIME_STORAGE_FORMAT/8.4.x"><span class="geshifilter"><code class="php geshifilter-php">DATETIME_DATETIME_STORAGE_FORMAT</code></span></a>). That way, we'll get reliable results. In the example above I just wanted to filter by the current time, but you can pass a date string to the <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Datetime%21DrupalDateTime.php/function/DrupalDateTime%3A%3A__construct/8.4.x">constructor of DrupalDateTime</a> as well, if you want something else.</p> <p><strong>Please note:</strong> Starting with Drupal 8.5.x, the constants mentioned above have been <em>deprecated</em> in favor of constants on a new <a href="https://api.drupal.org/api/drupal/core%21modules%21datetime%21src%21Plugin%21Field%21FieldType%21DateTimeItemInterface.php/interface/DateTimeItemInterface/8.5.x"><span class="geshifilter"><code class="php geshifilter-php">DateTimeItemInterface</code></span></a>. They will be removed in Drupal 9.x.</p> <p>You can also get these objects directly from a date field's value by using <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21TypedData%21Type%21DateTimeInterface.php/interface/DateTimeInterface/8.4.x">getDateTime()</a>:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #b1b100;">foreach</span> <span style="color: #009900;">(</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">field_date_range</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">(</span><span style="color: #000088;">$item</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$index</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDateTime</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #009900;">}</span> <span style="color: #009900;">}</span></pre></div> <p>If you're using experimental date range fields, another thing you need to know is, that the end date is stored in an <span class="geshifilter"><code class="php geshifilter-php">end_value</code></span> column.</p> <p>Here's a more complete example querying for event nodes in the future:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> Drupal\Core\Datetime\DrupalDateTime<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">use</span> Drupal\Core\Language\LanguageInterface<span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// @note: In Drupal 8.5.x and later also include the following line:</span> <span style="color: #000000; font-weight: bold;">use</span> Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface<span style="color: #339933;">;</span>   <span style="color: #000088;">$storage</span> <span style="color: #339933;">=</span> \Drupal<span style="color: #339933;">::</span><span style="color: #004000;">service</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'entity_type.manager'</span><span style="color: #009900;">)</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getStorage</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'node'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$storage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getQuery</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'type'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'event'</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'status'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><a href="http://www.php.net/sort"><span style="color: #990000;">sort</span></a><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date_range.value'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'ASC'</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><a href="http://www.php.net/sort"><span style="color: #990000;">sort</span></a><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date_range.end_value'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'ASC'</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><a href="http://www.php.net/sort"><span style="color: #990000;">sort</span></a><span style="color: #009900;">(</span><span style="color: #0000ff;">'created'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'ASC'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'langcode'</span><span style="color: #339933;">,</span> <span style="color: #009900;">[</span> \Drupal<span style="color: #339933;">::</span><span style="color: #004000;">service</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'language_manager'</span><span style="color: #009900;">)</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCurrentLanguage</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">,</span> LanguageInterface<span style="color: #339933;">::</span><span style="color: #004000;">LANGCODE_NOT_APPLICABLE</span><span style="color: #339933;">,</span> LanguageInterface<span style="color: #339933;">::</span><span style="color: #004000;">LANGCODE_NOT_SPECIFIED</span><span style="color: #339933;">,</span> <span style="color: #009900;">]</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'IN'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// @note BEGIN: Code for Drupal 8.5.x and later: </span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DrupalDateTime<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTimezone</span><span style="color: #009900;">(</span><span style="color: #000000; font-weight: bold;">new</span> \DateTimeZone<span style="color: #009900;">(</span>DateTimeItemInterface<span style="color: #339933;">::</span><span style="color: #004000;">STORAGE_TIMEZONE</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #009900;">(</span>DateTimeItemInterface<span style="color: #339933;">::</span><span style="color: #004000;">DATETIME_STORAGE_FORMAT</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// @node END: Code for Drupal 8.5.x and later.</span>   <span style="color: #666666; font-style: italic;">// @note BEGIN: Code for Drupal 8.4.x and earlier:</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DrupalDateTime<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTimezone</span><span style="color: #009900;">(</span><span style="color: #000000; font-weight: bold;">new</span> \DateTimeZone<span style="color: #009900;">(</span>DATETIME_STORAGE_TIMEZONE<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #009900;">(</span>DATETIME_DATETIME_STORAGE_FORMAT<span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// @node END: Code for Drupal 8.4.x and earlier.</span>   <span style="color: #000088;">$and</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">andConditionGroup</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date_range.value'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$date</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&gt;'</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><span style="color: #004000;">notExists</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date_range.end_value'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #000088;">$or</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">orConditionGroup</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #000088;">$and</span><span style="color: #009900;">)</span> <span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'field_date_range.end_value'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$date</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&gt;'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">condition</span><span style="color: #009900;">(</span><span style="color: #000088;">$or</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #000088;">$ids</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$storage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadMultiple</span><span style="color: #009900;">(</span><span style="color: #000088;">$ids</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span></pre></div> <p>Note, that there's currently <a href="https://www.drupal.org/project/drupal/issues/2580265">an issue in Drupal Core</a> with nested condition groups in entity query, which are used in the example above.</p> <p><strong>Update:</strong> This post has been updated to reflect changes in Drupal 8.5.x (see <a href="https://www.drupal.org/node/2912980">Global constants in datetime.module are deprecated and DateTimeItemInterface has been introduced</a>).</p> </div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/date" class="label label-default" hreflang="de">date</a> <a href="/en/tags/date-range" class="label label-default" hreflang="en">date range</a> <a href="/en/tags/languagemanager" class="label label-default" hreflang="en">LanguageManager</a> <a href="/en/tags/getcurrentlanguage" class="label label-default" hreflang="en">getCurrentLanguage</a> <a href="/en/tags/languageinterface" class="label label-default" hreflang="en">LanguageInterface</a> <a href="/en/tags/drupaldatetime" class="label label-default" hreflang="en">DrupalDateTime</a> <a href="/en/tags/entity-query" class="label label-default" hreflang="en">entity query</a> <a href="/en/tags/entitytypemanager" class="label label-default" hreflang="en">EntityTypeManager</a> <a href="/en/tags/datetimeiteminterface" class="label label-default" hreflang="en">DateTimeItemInterface</a> </div> Mon, 05 Feb 2018 07:09:16 +0000 patrick 134 at https://blog.werk21.de Install pfsense 2.4.x on xen (Ubuntu 16.04) https://blog.werk21.de/en/2017/12/17/install-pfsense-24x-xen-ubuntu-1604 <span>Install pfsense 2.4.x on xen (Ubuntu 16.04)</span> <span><span lang="" about="/en/user/15" typeof="schema:Person" property="schema:name" datatype="">kelly</span></span> <span>Sun, 12/17/2017 - 17:43</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>pfsense 2.4.x is not available as nano-image, so you have to install pfsense as xen-Guest via vnc.</p> <h2>Download pfsense</h2> <p>Download pfsense from <a href="https://www.pfsense.org/download/">https://www.pfsense.org/download/</a> (AMD64, CD Image (ISO) Installer)</p> <h2>Configure Xen</h2> <p>You have to create a LV or another device to install.</p> <div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;">builder <span style="color: #000080;">=</span> <span style="color: #FF0000;">'hvm'</span> vcpus <span style="color: #000080;">=</span> <span style="color: #FF0000;">'4'</span> memory <span style="color: #000080;">=</span> <span style="color: #FF0000;">'2048'</span> &nbsp; disk <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span> <span style="color: #FF0000;">'phy:/dev/xenvg/pfsense-disk,hda,w'</span>, <span style="color: #FF0000;">'file:/root/pfSense-CE-2.4.2-RELEASE-amd64.iso,hdc:cdrom,r'</span> <span style="color: #008000;">&#93;</span> &nbsp; serial <span style="color: #000080;">=</span> <span style="color: #FF0000;">'pty'</span> &nbsp; vnc <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span> vnclisten <span style="color: #000080;">=</span> <span style="color: #FF0000;">'0.0.0.0'</span> &nbsp; boot <span style="color: #000080;">=</span> <span style="color: #FF0000;">'d'</span> &nbsp; name <span style="color: #000080;">=</span> <span style="color: #FF0000;">'pfsense'</span> &nbsp; vif <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span> <span style="color: #FF0000;">'ip=xxx.xxx.xxx.xxx,bridge=xenbr0'</span>, <span style="color: #FF0000;">'ip=yyy.yyy.yyy.yyy,bridge=xenbr1'</span>, <span style="color: #FF0000;">'ip=zzz.zzz.zzz.zzz,bridge=xenbr2'</span>, <span style="color: #008000;">&#93;</span></pre></div> <h2>Installing pfsense</h2> <p>Create Guest (xl create) and connect with your vncviewer (<a href="https://www.realvnc.com/en/connect/download/viewer/">https://www.realvnc.com/en/connect/download/viewer/</a>)</p> <p>(Remark: We had to add internal route / tunnel to access webgui via browser)</p> <h2>After installing pfsense</h2> <p>After installing remove lines for booting and vnc:</p> <div class="geshifilter"><pre class="cpp geshifilter-cpp" style="font-family:monospace;">builder <span style="color: #000080;">=</span> <span style="color: #FF0000;">'hvm'</span> vcpus <span style="color: #000080;">=</span> <span style="color: #FF0000;">'4'</span> memory <span style="color: #000080;">=</span> <span style="color: #FF0000;">'2048'</span> &nbsp; disk <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span> <span style="color: #FF0000;">'phy:/dev/xenvg/pfsense-disk,hda,w'</span> <span style="color: #008000;">&#93;</span> &nbsp; serial <span style="color: #000080;">=</span> <span style="color: #FF0000;">'pty'</span> &nbsp; name <span style="color: #000080;">=</span> <span style="color: #FF0000;">'pfsense'</span> &nbsp; vif <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span> <span style="color: #FF0000;">'ip=xxx.xxx.xxx.xxx,bridge=xenbr0'</span>, <span style="color: #FF0000;">'ip=yyy.yyy.yyy.yyy,bridge=xenbr1'</span>, <span style="color: #FF0000;">'ip=zzz.zzz.zzz.zzz,bridge=xenbr2'</span>, <span style="color: #008000;">&#93;</span></pre></div> <h2>Important Network-settings</h2> <p>Under https://&lt;your_host&gt;/system_advanced_network.php you have to check following options (check to disable):</p> <ul> <li>Hardware Checksum Offloading</li> <li>Hardware TCP Segmentation Offloading</li> <li>Hardware Large Receive Offloading</li> </ul> <p> </p> <p> </p></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/server" class="label label-default" hreflang="de">Server</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/xen" class="label label-default" hreflang="de">xen</a> <a href="/de/tags/ubuntu" class="label label-default" hreflang="de">ubuntu</a> <a href="/en/tags/pfsense" class="label label-default" hreflang="en">pfsense</a> </div> Sun, 17 Dec 2017 16:43:23 +0000 kelly 130 at https://blog.werk21.de Dealing with *DEPTH TOO GREAT* in Kint https://blog.werk21.de/en/2017/12/13/dealing-depth-too-great-kint <span>Dealing with *DEPTH TOO GREAT* in Kint</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Wed, 12/13/2017 - 08:58</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>If you use <a href="https://drupal.org/project/devel">Devel</a>'s <span class="geshifilter"><code class="php geshifilter-php">dpm<span style="color: #009900;">(</span><span style="color: #009900;">)</span></code></span> with <a href="https://github.com/kint-php/kint">Kint</a> for debugging in Drupal 8, chances are you already encountered the message <span class="geshifilter"><code class="php geshifilter-php"><span style="color: #339933;">*</span>DEPTH TOO GREAT<span style="color: #339933;">*</span></code></span> when clicking through a deeply nested object.</p> <p>There is a reason for that: Performance. Always rendering all levels of a deeply nested object might result in either your server or your browser to run out of resources and fail. That's why there is a maximum number of levels to show. It's usually at <span class="geshifilter"><code class="php geshifilter-php"><span style="color: #cc66cc;">7</span></code></span> levels.</p> <p>If you need to inspect something that is nested further below, the best thing to do is to limit the <span class="geshifilter"><code class="php geshifilter-php">dpm<span style="color: #009900;">(</span><span style="color: #009900;">)</span></code></span> to a more explicit part of the nested variable. But sometimes you can't or don't want to do that. In those cases, you can increase the maximum levels by placing</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">kint_require<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> \Kint<span style="color: #339933;">::</span><span style="color: #000088;">$maxLevels</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">;</span></pre></div> <p>somewhere above your <span class="geshifilter"><code class="php geshifilter-php">dpm<span style="color: #009900;">(</span><span style="color: #009900;">)</span></code></span> call. <span class="geshifilter"><code class="php geshifilter-php"><span style="color: #000088;">$maxLevels</span></code></span> is of course the maximum number of levels you want to see. If you know what you're doing, you could even use</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">\Kint<span style="color: #339933;">::</span><span style="color: #000088;">$maxLevels</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></pre></div> <p>to remove the limit entirely. Use at your own risk.</p> </div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/devel" class="label label-default" hreflang="de">Devel</a> <a href="/en/tags/kint" class="label label-default" hreflang="en">Kint</a> <a href="/en/tags/dpm" class="label label-default" hreflang="en">dpm</a> </div> Wed, 13 Dec 2017 07:58:54 +0000 patrick 129 at https://blog.werk21.de Change source id mapping of a Drupal 8 migration https://blog.werk21.de/en/2017/12/13/change-source-id-mapping-drupal-8-migration <span>Change source id mapping of a Drupal 8 migration</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Wed, 12/13/2017 - 06:57</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Drupal Core's Migrate API maintains an internal table mapping unique source ids to destination ids. This is usually done via a database table that holds the field values that together uniquely identify a source row and the matching destination id of the entity in Drupal. The field names and types that uniquely identify a source row are provided by the source plugin of a migration. In most cases, you just have some kind of an id column, but migrate supports any number of fields for the primary key of the source row.</p> <p>Recently I was dealing with a migration that was using the <span class="geshifilter"><code class="php geshifilter-php">Url</code></span> source plugin provided by <a href="https://drupal.org/project/migrate_plus">Migrate Plus</a> to import files from an <span class="geshifilter"><code class="php geshifilter-php">XML</code></span> source. The source plugins provided by Migrate Plus allow you to specify the ids returned by <a href="https://api.drupal.org/api/drupal/core%21modules%21migrate%21src%21Plugin%21MigrateSourceInterface.php/function/MigrateSourceInterface%3A%3AgetIds/8.4.x">MigrateSourceInterface::getIds()</a> in the <span class="geshifilter"><code class="php geshifilter-php">YML</code></span> file of your migrations. Originally I used a simple id map like this:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">source<span style="color: #339933;">:</span> ids<span style="color: #339933;">:</span> id<span style="color: #339933;">:</span> type<span style="color: #339933;">:</span> integer</pre></div> <p>Unfortunately, I later noticed that I needed to add the file name as a second key to the id map, so I changed the YML file to something like this:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"> ids<span style="color: #339933;">:</span> id<span style="color: #339933;">:</span> type<span style="color: #339933;">:</span> integer file_name<span style="color: #339933;">:</span> type<span style="color: #339933;">:</span> string</pre></div> <p>So far so good. When I wanted to update the migration, I was greeted by this error message:</p> <blockquote> <p>Migration failed with source plugin exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column "sourceid2" in<br /> "field list": INSERT INTO {migrate_map_example_file} (source_ids_hash, sourceid1, sourceid2, source_row_status,<br /> rollback_action, hash, last_imported) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2,<br /> :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6); Array<br /> (<br />     [:db_insert_placeholder_0] =&gt; a8d0cbb8ca5f48c73993244fd275342d84b92a2eb33300b0852ef560f70aa55d<br />     [:db_insert_placeholder_1] =&gt; 10817<br />     [:db_insert_placeholder_2] =&gt;<br />     [:db_insert_placeholder_3] =&gt; 2<br />     [:db_insert_placeholder_4] =&gt; 0<br />     [:db_insert_placeholder_5] =&gt;<br />     [:db_insert_placeholder_6] =&gt; 1513082182<br /> )  </p> </blockquote> <p>Solving this is actually way easier than I thought. Just drop the migrate mapping table for your migration from the SQL database:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">DROP TABLE migrate_map_example_file<span style="color: #339933;">;</span></pre></div> <p>If you are less adventurous, you might just want to rename the table initially:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><a href="http://www.php.net/rename"><span style="color: #990000;">RENAME</span></a> TABLE migrate_map_example_file TO migrate_map_example_file_backup<span style="color: #339933;">;</span></pre></div> <p>As soon as you rerun your migration, migrate will recreate the table for you, this time using the new id mapping. Voilá.</p> </div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/migrate" class="label label-default" hreflang="de">migrate</a> <a href="/en/tags/migrateplus" class="label label-default" hreflang="en">migrate_plus</a> <a href="/en/tags/source" class="label label-default" hreflang="en">source</a> <a href="/en/tags/url" class="label label-default" hreflang="en">Url</a> <a href="/en/tags/migratesourceinterface" class="label label-default" hreflang="en">MigrateSourceInterface</a> <a href="/en/tags/getids" class="label label-default" hreflang="en">getIds</a> </div> Wed, 13 Dec 2017 05:57:34 +0000 patrick 128 at https://blog.werk21.de Illegal mix of collations exception caused by Drupal 8 Autocomplete with Entity Reference View https://blog.werk21.de/en/2017/09/08/illegal-mix-collations-exception-caused-drupal-8-autocomplete-entity-reference-view <span>Illegal mix of collations exception caused by Drupal 8 Autocomplete with Entity Reference View</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Fri, 09/08/2017 - 11:48</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Looking at a <em>Recent log messages</em> report of one of our Drupal 8 instaces, I came across this error message:</p> <blockquote> <p><em>Drupal\Core\Database\DatabaseExceptionWrapper</em>: Exception in Media Autocomplete[media_autocomplete]: SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (ascii_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation 'like': SELECT media_field_data.langcode AS media_field_data_langcode, media_field_data.mid AS mid, media_field_data.name AS media_field_data_name, media_field_data.bundle AS media_field_data_bundle FROM {media_field_data} media_field_data WHERE ((media_field_data.bundle = :db_condition_placeholder_0) AND ((media_field_data.name LIKE :db_condition_placeholder_1 ESCAPE '\\') OR (media_field_data.bundle LIKE :db_condition_placeholder_2 ESCAPE '\\'))) AND ((media_field_data.status = :db_condition_placeholder_3) AND (media_field_data.langcode IN (:db_condition_placeholder_4, :db_condition_placeholder_5, :db_condition_placeholder_6))) LIMIT 10 OFFSET 0; Array ( [:db_condition_placeholder_0] =&gt; image [:db_condition_placeholder_1] =&gt; %gläsernes labor% [:db_condition_placeholder_2] =&gt; %gläsernes labor% [:db_condition_placeholder_3] =&gt; 1 [:db_condition_placeholder_4] =&gt; de [:db_condition_placeholder_5] =&gt; und [:db_condition_placeholder_6] =&gt; zxx ) in <em>Drupal\views\Plugin\views\query\Sql-&gt;execute()</em> (line <em>1488</em> of <em>core/modules/views/src/Plugin/views/query/Sql.php</em>).</p> </blockquote> <p>Clearly, an editor was trying to use the autocomplete functionality of an entity reference field searching for media entities matching the search string "gläsernes labor" (in English: <em>transparent laboratory</em>). This would actually happen for any search string entered into the autocomplete that didn't contain ascii characters only, so in this case the "ä" in "gläsernes" was causing the exception. Looking closer at the query, we can see that the MySQL table is "media_field_data" and the search string is in two placeholders: "db_condition_placeholder_1" and "db_condition_placeholder_2". These are used to check for matches in "media_field_data.name" or "media_field_data.bundle" columns. So I asked the database for the collation of these fields:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;">MariaDB <span style="color: #009900;">&#91;</span>my_drupal_8_database<span style="color: #009900;">&#93;</span><span style="color: #339933;">&gt;</span> SELECT TABLE_NAME<span style="color: #339933;">,</span> COLUMN_NAME<span style="color: #339933;">,</span> COLLATION_NAME FROM INFORMATION_SCHEMA<span style="color: #339933;">.</span>COLUMNS WHERE TABLE_SCHEMA<span style="color: #339933;">=</span><span style="color: #0000ff;">'my_drupal_8_database'</span> AND TABLE_NAME<span style="color: #339933;">=</span><span style="color: #0000ff;">'media_field_data'</span> AND COLUMN_NAME IN <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bundle'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #339933;">+------------------+-------------+--------------------+</span> <span style="color: #339933;">|</span> TABLE_NAME <span style="color: #339933;">|</span> COLUMN_NAME <span style="color: #339933;">|</span> COLLATION_NAME <span style="color: #339933;">|</span> <span style="color: #339933;">+------------------+-------------+--------------------+</span> <span style="color: #339933;">|</span> media_field_data <span style="color: #339933;">|</span> bundle <span style="color: #339933;">|</span> ascii_general_ci <span style="color: #339933;">|</span> <span style="color: #339933;">|</span> media_field_data <span style="color: #339933;">|</span> name <span style="color: #339933;">|</span> utf8mb4_general_ci <span style="color: #339933;">|</span> <span style="color: #339933;">+------------------+-------------+--------------------+</span></pre></div> <p>Tada! The bundle column of the table uses ascii collation. For our autocomplete search to work, those two columns would need to have the same collation or we would need to change the query to specify the collation to use for each like condition separately. Another option would be to just query the name field or the bundle field.</p> <p>But why was the bundle field searched in the first place? We set up an entity reference view for this entity reference field (after applying a <a href="https://www.drupal.org/node/2174633">patch</a>, mind you ;). We did this because we wanted to show the bundle and some other stuff along the label of the entity in the results returned by the autocomplete. When we set up the view we selected "Name" and "Bundle" for the "Search fields" setting of the "Entity reference list" style plugin.</p> <p>Our client didn't really care that much about searching the bundle field, so I just removed it from the search fields. And voilá, you could enter strings with umlauts into the autocomplete again.</p></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/en/tags/autocomplete" class="label label-default" hreflang="en">Autocomplete</a> <a href="/de/tags/views" class="label label-default" hreflang="de">Views</a> <a href="/en/tags/entity-reference-field" class="label label-default" hreflang="en">Entity Reference Field</a> <a href="/de/tags/mysql" class="label label-default" hreflang="de">mysql</a> <a href="/en/tags/exception" class="label label-default" hreflang="en">Exception</a> </div> Fri, 08 Sep 2017 09:48:14 +0000 patrick 127 at https://blog.werk21.de Change list of valid URI schemes in Drupal 8 https://blog.werk21.de/en/2017/06/06/change-list-valid-uri-schemes-drupal-8 <span>Change list of valid URI schemes in Drupal 8</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Tue, 06/06/2017 - 13:12</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>If you need to support <em>obscure</em> <a href="https://en.wikipedia.org/wiki/Uniform_Resource_Identifier">URI schemes</a> in your Drupal 8 instance and you're getting error messages about invalid URI schemes, this post is for you.</p> <p>Suppose a customer asks you to add a <em>WhatsApp</em> Share Link somewhere. It might look something like this:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> \Drupal\Core\Url<span style="color: #339933;">;</span> &nbsp; Url<span style="color: #339933;">:</span>fromUri<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'whatsapp://send'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">'query'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">'text'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Some text'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div> <p>This should work, since the URI is perfectly valid per the specification. But instead of the desired link, we'll get this error message, that results in a white page:</p> <blockquote> <em>InvalidArgumentException</em>: The URI 'whatsapp://send' is invalid. You must use a valid URI scheme. Use base: for a path, e.g., to a Drupal file that needs the base path. Do not use this for internal paths controlled by Drupal. in <em>Drupal\Core\Utility\UnroutedUrlAssembler-&gt;assemble()</em> (line <em>64</em> of <em>core/lib/Drupal/Core/Utility/UnroutedUrlAssembler.php</em>). </blockquote> <p>What happened here? Drupal 8 actually maintains a list of <em>valid</em> URI schemes, that are allowed to be used during URL generation. If a scheme is not in this list of protocols, it will result in this error message. <span class="geshifilter"><code class="php geshifilter-php">whatsapp</code></span> is not included in this list by default, so Drupal considers the URI to be invalid.</p> <p>This is actually a nice security feature, but what if we just need to support schemes other than the default? It's easy and quickly done, as long as you know where to look. The allowed protocols are specified as a parameter to the services container. The parameter in question is called <span class="geshifilter"><code class="php geshifilter-php">filter_protocols</code></span>. The default parameters for the services container are set in a file called <span class="geshifilter"><code class="php geshifilter-php"><span style="color: #b1b100;">default</span><span style="color: #339933;">.</span>services<span style="color: #339933;">.</span>yml</code></span> in the <span class="geshifilter"><code class="php geshifilter-php">sites<span style="color: #339933;">/</span><span style="color: #b1b100;">default</span></code></span> directory of your Drupal installation. You could also use a <span class="geshifilter"><code class="php geshifilter-php">development<span style="color: #339933;">.</span>services<span style="color: #339933;">.</span>yml</code></span> file just for development and more. If you want to change any of the settings, copy the <span class="geshifilter"><code class="php geshifilter-php"><span style="color: #b1b100;">default</span><span style="color: #339933;">.</span>services<span style="color: #339933;">.</span>yml</code></span> file to <span class="geshifilter"><code class="php geshifilter-php">services<span style="color: #339933;">.</span>yml</code></span> and change the settings there as needed. To support e.g. the <span class="geshifilter"><code class="php geshifilter-php">whatsapp</code></span> protocol, we would need to add that to the list defined by the <span class="geshifilter"><code class="php geshifilter-php">filtered_protocols</code></span> parameter. Now rebuild your container (e.g. by calling <span class="geshifilter"><code class="php geshifilter-php">drush cr</code></span> on the command line) and the error message should be gone.</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Allowed protocols for URL generation. </span>parameters<span style="color: #339933;">:</span> filter_protocols<span style="color: #339933;">:</span> <span style="color: #339933;">-</span> http <span style="color: #339933;">-</span> https <span style="color: #339933;">-</span> ftp <span style="color: #339933;">-</span> news <span style="color: #339933;">-</span> nntp <span style="color: #339933;">-</span> tel <span style="color: #339933;">-</span> telnet <span style="color: #339933;">-</span> mailto <span style="color: #339933;">-</span> irc <span style="color: #339933;">-</span> ssh <span style="color: #339933;">-</span> sftp <span style="color: #339933;">-</span> webcal <span style="color: #339933;">-</span> rtsp <span style="color: #339933;">-</span> whatsapp</pre></div> <p>Of course you could also remove any schemes you don't need, e.g. <span class="geshifilter"><code class="php geshifilter-php">telnet</code></span> for increased security ;).</p></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/en/tags/servicesyml" class="label label-default" hreflang="en">services.yml</a> <a href="/en/tags/url" class="label label-default" hreflang="en">Url</a> </div> Tue, 06 Jun 2017 11:12:50 +0000 patrick 121 at https://blog.werk21.de Programmatically change views pager type or options https://blog.werk21.de/en/2017/04/21/programmatically-change-views-pager-type-or-options <span>Programmatically change views pager type or options</span> <span><span lang="" about="/en/user/8" typeof="schema:Person" property="schema:name" datatype="">patrick</span></span> <span>Fri, 04/21/2017 - 08:12</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>Suppose you have a view and want to dynamically alter the number of results shown by the view based on the view arguments. <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21src%21ViewExecutable.php/class/ViewExecutable/8.3.x">ViewExecutable</a> provides a <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21src%21ViewExecutable.php/function/ViewExecutable%3A%3AsetItemsPerPage/8.3.x">setItemsPerPage()</a> method, so this seems easily done at a first glance, but – as always – the devil is in the details.</p> <p>If we don't have the <span class="geshifilter"><code class="php geshifilter-php">ViewExecutable</code></span> object, yet, the best thing to do is implement a <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21views.api.php/8.3.x">hook provided by the Views module</a> first. Don't do that in your module file as you would with other hooks, but instead create a new file <span class="geshifilter"><code class="php geshifilter-php">module_name<span style="color: #339933;">.</span>views_execution<span style="color: #339933;">.</span>inc</code></span> in the root folder of your custom module and implement the hook there. Views module will load this file as needed. A good hook to make changes to the pager is <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21views.api.php/function/hook_views_pre_view/8.3.x">hook_views_pre_view()</a>, right at the beginning of the initialization phase.</p> <p>Another helpful method provided by <span class="geshifilter"><code class="php geshifilter-php">ViewExecutable</code></span> is <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21src%21ViewExecutable.php/function/ViewExecutable%3A%3AsetOffset/8.3.x">setOffset()</a>, which allows you to modify the offset (e.g. skip the first 2 items of the results).</p> <p>Important caveat: If you're using a pager plugin, that doesn't use these options, then calls to those methods will have no effect. So if you're using the <span class="geshifilter"><code class="php geshifilter-php">none</code></span> pager plugin (i.e. <em>Display all results</em> pager setting in the UI), the view will always show all results, even if you call the <span class="geshifilter"><code class="php geshifilter-php">setItemsPerPage<span style="color: #009900;">(</span><span style="color: #009900;">)</span></code></span> method on it. In that case, you need to change to a pager plugin that uses this setting first (e.g. <span class="geshifilter"><code class="php geshifilter-php">some</code></span>, which is equivalent to the <em>Display a specified number of items</em> setting in the UI). To do so, we can get the pager option from the <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21display%21DisplayPluginInterface.php/interface/DisplayPluginInterface/8.3.x">display handler</a> using the <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21display%21DisplayPluginInterface.php/function/DisplayPluginInterface%3A%3AgetOption/8.3.x">getOption()</a> method. This will return an array with a type key and an options key. The type value is a string, that contains the name of the pager plugin and the options value is an array that contains all the settings of the pager plugin. After changing this array as needed, we can use the <a href="https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21display%21DisplayPluginInterface.php/function/DisplayPluginInterface%3A%3AsetOption/8.3.x">setOption()</a> method to update the pager options. That way, you can also change any other options of pager plugins, that you may need to change. Just modify the options array as needed.</p> <p>Let's see how this would look in code:</p> <div class="geshifilter"><pre class="php geshifilter-php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>   <span style="color: #009933; font-style: italic;">/** * @file * Hook implementations for hooks provided by Views API. */</span>   <span style="color: #000000; font-weight: bold;">use</span> Drupal\views\ViewExecutable<span style="color: #339933;">;</span>   <span style="color: #009933; font-style: italic;">/** * Implements hook_views_pre_view(). */</span> <span style="color: #000000; font-weight: bold;">function</span> example_views_pre_view<span style="color: #009900;">(</span>ViewExecutable <span style="color: #000088;">$view</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'example_view'</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current_display</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'display_id'</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #666666; font-style: italic;">// Show only three items. This assumes, that we already use a pager plugin, </span> <span style="color: #666666; font-style: italic;">// that uses this option. Otherwise it wouldn't have any effect.</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setItemsPerPage</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Skip the first 5 items. Again, this assumes, that we already use a </span> <span style="color: #666666; font-style: italic;">// pager plugin, that uses this option. Otherwise it wouldn't have any </span> <span style="color: #666666; font-style: italic;">// effect.</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOffset</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// If we need to change the pager type or other options of the pager, we </span> <span style="color: #666666; font-style: italic;">// need to modify the pager option of the display handler.</span> <span style="color: #000088;">$pager</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display_handler</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'pager'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// Change the pager plugin. Some will show a specified number of results.</span> <span style="color: #000088;">$pager</span><span style="color: #009900;">[</span><span style="color: #0000ff;">'type'</span><span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'some'</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// All options used by the plugin are available in $pager['options'].</span> <span style="color: #666666; font-style: italic;">// If you want to change them, that's fine. You just need to know the keys.</span>   <span style="color: #666666; font-style: italic;">// Update pager option of the display handler.</span> <span style="color: #000088;">$view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display_handler</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOption</span><span style="color: #009900;">(</span><span style="color: #0000ff;">'pager'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pager</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #009900;">}</span> <span style="color: #009900;">}</span></pre></div></div> <div class="field field--name-field-systems field--type-entity-reference field--label-inline"> <div class="field--label">Systems</div> <a href="/de/systems/drupal-8" class="label label-default" hreflang="de">Drupal 8</a> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-inline"> <div class="field--label">Tags</div> <a href="/de/tags/view" class="label label-default" hreflang="de">view</a> <a href="/en/tags/viewexecutable" class="label label-default" hreflang="en">ViewExecutable</a> <a href="/en/tags/pager" class="label label-default" hreflang="en">pager</a> <a href="/en/tags/setitemsperpage" class="label label-default" hreflang="en">setItemsPerPage</a> <a href="/en/tags/setoffset" class="label label-default" hreflang="en">setOffset</a> <a href="/en/tags/hookviewspreview" class="label label-default" hreflang="en">hook_views_pre_view</a> <a href="/en/tags/displayplugininterface" class="label label-default" hreflang="en">DisplayPluginInterface</a> <a href="/en/tags/getoption" class="label label-default" hreflang="en">getOption</a> <a href="/en/tags/setoption" class="label label-default" hreflang="en">setOption</a> </div> Fri, 21 Apr 2017 06:12:26 +0000 patrick 119 at https://blog.werk21.de