MiTo Team - We do not look for easy ways. We implement them. https://www.mito-team.com/en en Switching to Debian 12 "bookworm" https://www.mito-team.com/en/blog/2023/switching-debian-12-bookworm <span class="field field--name-title field--type-string field--label-hidden">Switching to Debian 12 &quot;bookworm&quot;</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>Debian 12 <em>bookworm</em> was released on June 10th, 2023. And next day we tried to use it (in development environment). And it went unexpectedly easy, there were no problems at all. So we started to plan migration for all servers in three steps: development servers, testing (staging) servers, production servers. And today we finished migration of all production servers to Debian 12 <em>bookworm</em>.</p><p>From our 20 years of experience of using Debian Linux transition from <em>bullseye</em> to <em>bookworm</em> was smoothest and easiest ever.</p><p>Thanks to everyone participated in creating such a great product. One more donation from our team. And long live the Debian!</p><p>P.S.: There was just one question with MySQL (the have no package for <em>bookworm</em> yet). But is works without any problems being installed from <em>bullseye</em> package.</p></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2023-08-03T10:49:18+03:00" title="Thursday, August 3, 2023 - 10:49" class="datetime">Thu, 2023-08-03 - 10:49</time> </span> Thu, 03 Aug 2023 07:49:18 +0000 mishutka 32 at https://www.mito-team.com Switching to Drupal 10 https://www.mito-team.com/en/blog/2023/switching-drupal-10 <span class="field field--name-title field--type-string field--label-hidden">Switching to Drupal 10</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p><a href="https://www.drupal.org/blog/drupal-10-0-0">Drupal 10 is out</a> for more than two months already! And this is extremely exciting.</p><p>Usually it takes from a year to switch to new core version: a lot of modules to upgrade, significant code changes. But Drupal 10 has almost the same core code as previous generation Drupal 9.5. There is a lot of deprecated code removed, there are some new features, but most of 9.5-compatible code runs without any problems with 10.0-core.</p><p>Most annoying issue is that not all contrib modules declared their support for Drupal 10. Usually the only change required is to add "<em>^10</em>" core version to <em>.info</em> file. So while waiting for maintainers to do this we using <a href="https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer" target="_blank">this temporary approach</a> to overcome this.</p><p>Next major technological milestone will be switching infrastructure to new <strong>PHP 8.2</strong>. Benchmarks promise 3-8% to overall performance. Will see.</p><p><strong>P.S.</strong>: This site is already on Drupal 10.</p></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2023-02-16T08:32:06+03:00" title="Thursday, February 16, 2023 - 08:32" class="datetime">Thu, 2023-02-16 - 08:32</time> </span> Thu, 16 Feb 2023 05:32:06 +0000 mishutka 31 at https://www.mito-team.com PHP 8.2 support added for our composer compatible version of JpGraph library https://www.mito-team.com/en/blog/2022/php-82-support-added-our-composer-compatible-version-jpgraph-library <span class="field field--name-title field--type-string field--label-hidden">PHP 8.2 support added for our composer compatible version of JpGraph library</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>As usual long story short: <a href="https://packagist.org/packages/mitoteam/jpgraph">https://packagist.org/packages/mitoteam/jpgraph</a>.</p> <p>We added patches to avoid PHP 8.2 warnings and some deprecation notices. Our internal tests are passing. Plus we have several confirmations from other users about no problems with PHP 8.2. So version 10.2.1 marked as <em>release candidate</em> and seems to be ready for production usage.</p> <p>We'll mark it <em>stable</em> as soon as PHP 8.2 released (expected on November 24, 2022).</p> <p>Original JpGraph library:&nbsp;<a href="https://jpgraph.net">https://jpgraph.net</a></p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2022-08-26T14:00:09+03:00" title="Friday, August 26, 2022 - 14:00" class="datetime">Fri, 2022-08-26 - 14:00</time> </span> Fri, 26 Aug 2022 11:00:09 +0000 mishutka 28 at https://www.mito-team.com Our composer package of JpGraph library used in PhpSpreadsheet https://www.mito-team.com/en/blog/2022/our-composer-package-jpgraph-library-used-phpspreadsheet <span class="field field--name-title field--type-string field--label-hidden">Our composer package of JpGraph library used in PhpSpreadsheet</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p><strong>Long Story Short</strong>: <a href="https://mttm.ml/38">PR</a> accepted by <a href="https://github.com/PHPOffice/PhpSpreadsheet">PHPOffice/PhpSpreadsheet</a> maintainers. So it will be included in next release.</p> <!--break--> <p>We use both JpGraph and&nbsp;PhpSpreadsheet intensively in our projects. But they were not intersected at all since we do not add charts to our spreadsheets.</p> <p>PHPOffice/PhpSpreadsheet used old abandoned jpgraph/jpgraph package to render charts in spreadsheets so there were no possibility to run it under PHP 8.1 without additional dances, drumming and code-patching.</p> <p>One of users asked us if our version of JpGraph compatible with PhpSpreadsheet. Answer was yes... but. Oh, there is always but. Investigation led us deep into&nbsp;PhpSpreadsheet's source code, solution was found and confirmed working. So we created pull-request and now it is accepted. The goal was not to break existing compatibility with old&nbsp;jpgraph/jpgraph. So now both abandoned jpgraph/jpgraph and actual&nbsp;<a href="https://packagist.org/packages/mitoteam/jpgraph">mitoteam/jpgraph</a> versions are supported by&nbsp;PhpSpreadsheet.</p> <p>Have a nice coding!</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2022-08-08T15:20:50+03:00" title="Monday, August 8, 2022 - 15:20" class="datetime">Mon, 2022-08-08 - 15:20</time> </span> Mon, 08 Aug 2022 12:20:50 +0000 mishutka 27 at https://www.mito-team.com mt-howmany: characters, lines, printed pages count for source code of project https://www.mito-team.com/en/blog/2022/mt-howmany <span class="field field--name-title field--type-string field--label-hidden">mt-howmany: characters, lines, printed pages count for source code of project</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>One day our team has discussion about how to estimate amount of source code for one of our projects. First idea was just calculate total files size, but... A whole bunch of questions arised immediately: there are a lot of vendor code in project, there are binary files, there are images, generated code, multi-byte character encodings and so on.</p><p>Our goal was to understand just how many pure code was written by our team. And we want to know characters, lines and printed-pages estimate counts for projects. So this pet-project was born as an answer to this questions.</p><p><strong>mt-howmany</strong> is <a href="https://getcomposer.org/doc/articles/vendor-binaries.md">composer based</a> command-line utility. It is installed like any composer package as a dependency:</p><pre><code class="language-plaintext">composer require mitoteam/mt-howmany </code></pre><p>Please take a look at GitHub project <a href="https://github.com/mitoteam/mt-howmany">page</a> for more details about installation and program usage.</p><p>Both UNIX-based and Windows OS are supported. All paths are relative to working directory, directory separators are changed from UNIX-ones (/) to Windows-ones (\) automatically when needed.</p><p>Unicode strings are handled by symfony/string package for proper characters count calculation. Tool supports exclusions by file extension or by file type. You can define custom characters per page and lines per page values in config.</p><p>Config files are in YAML. There is an ability to split config file to several files (importing one to another). We use this to have common part of config in common repository and individual per-project configs.</p><p>Program output example for <a href="/projects/binardo" target="_blank" rel="noopener">binardo</a> project:</p><pre><code class="language-plaintext">mt-howmany by MiTo Team ======================= Working directory: /www/binardo.mt.test Config file loaded: /www/binardo.mt.test/web/modules/custom/mtlapbase/mt-howmany.common.yml Config file loaded: /www/binardo.mt.test/mt-howmany.yml Results by file extension =========================  ----------- -------- ------------ ------------- -------   Type        Size     Characters   Files Count   Lines  ----------- -------- ------------ ------------- -------   php         777Kb    782756       174           32225   twig        50.0Kb   51145        26            1471   scss        29.8Kb   30464        47            1886   js          17.1Kb   17276        11            637   yml         15.5Kb   15767        18            621   sh          9.59Kb   9816         11            348   po          3.69Kb   2965         1             164   json        3.27Kb   3344         4             127   module      3.10Kb   3176         2             131   theme       3.06Kb   3133         2             123   gitignore   2.23Kb   2280         2             82   md          2.08Kb   1323         6             38   txt         139      139          1             8   htaccess    38       38           2             4  ----------- -------- ------------ ------------- ------- Totals ====== Types count: 14 Paths count: 67 Files count: 307 Size: 916Kb Characters: 923622 Lines: 37865 Pages by Characters: 257 Pages by Lines: 1052 </code></pre><ul><li><strong>Project Page</strong>: <a href="/projects/mt-howmany">mt-howmany</a></li><li><strong>GitHub</strong>: <a href="https://github.com/mitoteam/mt-howmany"><img style="max-width:100%;" src="https://img.shields.io/github/v/release/mitoteam/mt-howmany?style=flat-square&amp;logo=github" alt="GitHub Version" /></a></li></ul></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2022-06-16T17:05:26+03:00" title="Thursday, June 16, 2022 - 17:05" class="datetime">Thu, 2022-06-16 - 17:05</time> </span> Thu, 16 Jun 2022 14:05:26 +0000 mishutka 26 at https://www.mito-team.com Composer compatible version of JpGraph library with PHP 8.1 support https://www.mito-team.com/en/blog/2022/composer-compatible-version-jpgraph-library-php-81-support <span class="field field--name-title field--type-string field--label-hidden">Composer compatible version of JpGraph library with PHP 8.1 support</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>Long story short: <a href="https://packagist.org/packages/mitoteam/jpgraph">https://packagist.org/packages/mitoteam/jpgraph</a>.</p> <p>We use <a href="https://jpgraph.net" rel="noopener" target="_blank">JpGraph</a> library in several projects. It is looks like abandoned project: almost no updates from maintainers, website and documentation is not updated either. We tried to look for alternative... and there are none! All other charts libraries are either paid ones or have much less functionality. So we stayed with JpGraph.</p> <!-- break --> <p>First problem was composer support. There is 2022 already and all our php dependencies are managed with <strong>composer</strong>. So we created small wrapper for original JpGraph library with single class for comfortable use of JpGraph library in modern projects. This wrapper is available at <a href="https://packagist.org/packages/mitoteam/jpgraph">https://packagist.org/packages/mitoteam/jpgraph</a>.</p> <p>Now we upgrading our infrastructure from php 8.0 to <strong>8.1</strong>. Everything went fine with Drupal itself and its contrib modules. There were some minor changes in our code (deprecations mostly). But it was a huge amount of warnings in logs about deprecations in JpGraph code. So we had to decide either to stay at php 8.0 or try to patch JpGraph library to be compatible with php 8.1. And we did it! We managed to get rid of all the deprecation warnings from JpGraph.</p> <p>So we can declare php 8.1 support for our JpGraph wrapper at <a href="https://packagist.org/packages/mitoteam/jpgraph">https://packagist.org/packages/mitoteam/jpgraph</a> now.</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2022-02-25T19:24:58+03:00" title="Friday, February 25, 2022 - 19:24" class="datetime">Fri, 2022-02-25 - 19:24</time> </span> Fri, 25 Feb 2022 16:24:58 +0000 mishutka 21 at https://www.mito-team.com Moving site under Drupal 9 https://www.mito-team.com/en/blog/2022/moving-site-under-drupal-9 <span class="field field--name-title field--type-string field--label-hidden">Moving site under Drupal 9</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>"The shoemaker’s child always goes barefoot"... Our site was created under Drupal 6 CMS in 2008. It was almost frozen since 2012. It took several years to finally find a spare time to migrate out site to modern Drupal 9 CMS.</p> <p>For now we just moved all important content from old site and did some basic setup. There is a lot of work ahead. But at least is is possible now to&nbsp; add information about company, projects, team, skills and so on. So stay tuned, we'll do a lot of updates in near future.</p> <p>There are also couple ideas about technical articles for site.</p> <p>Hoooray!</p> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2022-02-13T18:47:47+03:00" title="Sunday, February 13, 2022 - 18:47" class="datetime">Sun, 2022-02-13 - 18:47</time> </span> Sun, 13 Feb 2022 15:47:47 +0000 mishutka 16 at https://www.mito-team.com "Collapse" button plugin for CKEditor for Drupal https://www.mito-team.com/en/article/2012/collapse-button-for-ckeditor-for-drupal <span class="field field--name-title field--type-string field--label-hidden">&quot;Collapse&quot; button plugin for CKEditor for Drupal</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>Several days ago I needed to add an ability to add "spoilers" to comments and nodes at <a href="http://veloby.net">VELOBY.NET</a> web site (Minsk's cycling community). Spoiler is a part of text, that is hidden from viewing by default. It expands by click showing previously hidden content to users.</p><p>I've googled nice <a href="http://drupal.org/project/collapse_text">Collapse Text</a> module for Drupal. Installed it, enabled in input format settings. Everything is fine with it.</p><p>We use <a href="http://drupal.org/project/ckeditor">CKEditor</a> as wysiwyg-editor on VELOBY.NET. And I wanted to add a button to its toolbar, to be able to insert <code>[collapsed]...[/collapsed]</code> meta tags before and after text, selected in editor. Googling almost an hour gave me nothing. So I decided to write own plugin for CKEditor with this functionality.</p><p>This small article is about creating this plugin.</p><p>There is a really good tutorial <a href="http://docs.cksource.com/CKEditor_3.x/Tutorials/Abbr_Plugin_Part_1">Creating a Simple CKEditor Plugin</a>. So I'm not reproducing whole plugin creation process here step-by-step. There will be only comments about final plugin code. Full source code is attached at the end of article.</p><p>First of all we think of name for new plugin and create a folder with this name. I chose <strong>mtcollapsed</strong> as plugin name.</p><p>Our plugin will add a button to editor's toolbar, so let take care about icon for it before starting coding. It should be 16x16 pixels, and I prefer PNG format. This is what I drew: <img style="height:16px;width:16px;" src="/sites/default/files/image/for-news/button.png" alt="" />. Gave it name <em>button.png</em> and put into our <em>mtcollapsed</em> directory.</p><p>Then I created an empty <em>plugin.js</em> file to put plugin code in. Our plugin consists of 3 parts: command, toolbar button, and dialog.</p><p>Command is really simple:</p><pre><code class="language-javascript">editor.addCommand('cmdMTCollapsedDialog', new CKEDITOR.dialogCommand('mtcollapsedDialog'));</code></pre><p>It adds command <em>cmdMTCollapsedDialog</em> that shows <em>mtcollapsedDialog</em> dialog.</p><p>Adding a toolbar is simple and easy to understand too:</p><pre><code class="language-javascript">editor.ui.addButton('MTcollapsed', { label: 'Insert spoiler', command: 'cmdMTCollapsedDialog', icon: this.path + 'button.png' }); </code></pre><p>This adds a button with <em>MTcollapsed</em> name with <em>Insert spoiler</em> label (tooltip), with our <em>button.png</em> as button's icon. Clicking this button executes our <em>cmdMTCollapsedDialog</em> command.</p><p>And here is most complicated part - dialog:</p><pre><code class="language-javascript">CKEDITOR.dialog.add( 'mtcollapsedDialog', function ( editor ) { return { title : 'Spoiler settings', minWidth : 300, minHeight : 200, contents : [{ id : 'tab1', label : 'Settings', elements : [{ type : 'text', id : 'title', label : 'Spoiler title', onShow : function() { this.setValue('Hidden text'); }, validate : CKEDITOR.dialog.validate.notEmpty( "Spoiler title should be provided" ) }] }], onOk : function() { var dialog = this; var title = dialog.getValueOf( 'tab1', 'title' ); var openTag = '[collapsed title=' + title + ']'; var closeTag = '[/collapsed]'; var inplaceTag = ' ' + openTag + ' text ' + closeTag + ' '; var S = editor.getSelection(); if( S == null) { editor.insertHtml(inplaceTag); return; } var R = S.getRanges(); R = R[0]; if( R == null) { editor.insertHtml(inplaceTag); return; } var startPos = Math.min(R.startOffset, R.endOffset); var endPos = Math.max(R.startOffset, R.endOffset); if( startPos == endPos ) { editor.insertHtml(inplaceTag); return; } var container = new CKEDITOR.dom.element('p'); var fragment = R.extractContents(); container.appendText(openTag); fragment.appendTo(container); container.appendText(closeTag); editor.insertElement(container); } }; });</code></pre><p>Lines 5-7: dialog parameters setup. Dialogs params described <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dialog.definition.html">here</a>.</p><p>Lines 8-20: Dialog's GUI elements. We just need one textbox (type = 'text') for user to be able to provide a title for hidden text. Line 17 sets default value for this textbox. Line 18 obliges user to provide a title.</p><p>Default dialog has two buttons: <em>OK</em> and <em>Cancel</em>. <em>Cancel</em> button just closes dialog without any other actions. Clicking <em>OK</em> button raises onOk event where most work is done (lines 21-61):</p><p>Line 24: accessing value provided by user in textbox.</p><p>Lines 26-28: preparing meta tags code to insert into editor. If there is a text selected open and close tags inserted before and after this text. If there are no text selected inline open-close metatag inserted ([collapsed title='title text'][/collapsed]).</p><p>Lines 30-36: Check if there is a selection in editor. Insert inline open-close metatag at cursor position if there is no selection.</p><p>Lines 38-45: Selection consists of ranges. We need first range of selection (actually there is alway just one range in selection). Insert inline open-close metatag at cursor position if there is no first range.</p><p>Lines 47-51: Sometimes there is a selection with a range, but this range starts and ends at the same position. This means that nothing still selected. Same thing: insert inline open-close metatag at cursor position.</p><p>If there is a selection wit a range we should create a container for its contents (because there could be severals elements selected, for example two paragraphs or paragrah and image).</p><p>Lines 53-54: Create container element and prepare range contents.</p><p>Lines 56-58: Adding open tag, range contents and close tag to our container.</p><p>Line 60: Insert container to editor at cursor position (replacing current selection).</p><p>Thats all! Full <em>plugin.js</em> source is in archive attached at the end of this article.</p><p>Now we should add our plugin to Drupal's CKEditor. There are two ways of adding plugind to CKEditor in Drupal:</p><ul><li>An easy one: just putting your plugin into "plugins" folder in CKEditor's module directory. This is really easy. But you'll have to keep this in mind everytime you updating the CKEditor module.</li><li>As part of own module: you should create owm Drupal module, or add some code to a new one.</li></ul><p>I have own module on VELOBY.NET site already, so second way is right for me. But you can try to experiment with first one. it should work as well. To add CKEditor plugin with own module your module should implement <em>hook_ckeditor_plugin</em> hook function. This hook should return an array with plugin definitions. There is only one plugin in our case.</p><p>This is what I've added to my <em>velobynet.module</em> file:</p><pre><code class="language-php">/** * CKEditor plugins hook */ function velobynet_ckeditor_plugin() { return array( 'mtcollapsed' =&gt; array( 'name' =&gt; 'mtcollapsed', 'desc' =&gt; 'MTCollapsed - ' . t('Inserts [collapsed][/collapsed] tags'), 'path' =&gt; drupal_get_path('module', 'velobynet') . '/ckeditor-plugins/mtcollapsed/', 'buttons' =&gt; array( 'MTcollapsed' =&gt; array('label' =&gt; 'Insert spoiler', 'icon' =&gt; 'button.png' ), ) ) ); }</code></pre><p>Line 7: Plugin name.</p><p>Line 8: Plugin description to show at CKEditor's settings page.</p><p>Line 9: Full path (with trailing slash) to plugin folder.</p><p>Lines 10-13: Plugin buttons definitions (optional). We define just one button with 'Insert spoiler' label and <em>button.png</em> icon.</p><p>After adding this we can enable plugin in some CKEditor's profile settings, and try how it works.</p><p>Thank you for reading this and excuse me for my English, it is far from perfect yet <img style="height:16px;width:16px;" src="/sites/default/files/image/for-news/smile.png" alt="" />.</p><p>Please <a href="/contact">contact us</a> if you have any questions.</p><p>Module was tested with <a href="http://drupal.org">Drupal</a> <strong>v.6.24</strong>, <a href="http://ckeditor.com">CKEditor</a> (itself) <strong>v.3.6.2</strong> and <a href="http://drupal.org/project/ckeditor">CKEditor</a> (Drupal module) <strong>v6.x-1.8</strong>.</p><h3>Downloads</h3><ul><li><a href="/sites/default/files/download/plugin-only.zip">plugin-only.zip</a> - contains only CKEditor's plugin code</li><li><a href="/sites/default/files/download/full-mtcollapsed-module.zip">full-mtcollapsed-module.zip</a> - Complete solution to install in Drupal as a module</li></ul></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2012-02-20T11:12:05+03:00" title="Monday, February 20, 2012 - 11:12" class="datetime">Mon, 2012-02-20 - 11:12</time> </span> Mon, 20 Feb 2012 08:12:05 +0000 mishutka 12 at https://www.mito-team.com Introducing new project: MT Browser Switcher https://www.mito-team.com/en/news/mtbs/initial-release <span class="field field--name-title field--type-string field--label-hidden">Introducing new project: MT Browser Switcher</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden"><p>We are glad to introduce you our new project: <a href="/projects/mt-browser-switcher"><strong>MT Browser Switcher</strong></a>!</p><p><img class="float-start me-3" style="height:32px;width:32px;" src="/sites/default/files/image/for-pages/mtbs-icon.png" alt="" />This small utility allows you to assign URLs to several different browsers so different websites can be opened with different browsers. This can be useful if you use some browser for everyday surfing but prefer another browser for particular websites. For example you use Opera for everyday surfing, but you prefer to work with your GMail account using Google Chrome since Google services work much more faster and more stable with Google's native browser.</p><p>More details are available at <a href="/projects/mt-browser-switcher">project page</a>. Please provide us with your feedback.</p></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span>mishutka</span></span> <span class="field field--name-created field--type-created field--label-hidden"><time datetime="2009-07-10T14:05:28+03:00" title="Friday, July 10, 2009 - 14:05" class="datetime">Fri, 2009-07-10 - 14:05</time> </span> Fri, 10 Jul 2009 11:05:28 +0000 mishutka 13 at https://www.mito-team.com