Invalid Form Token Please Reload This Form and Submit Again Https Concrete5


Monitor invalid SSL certificates

  • 27.04.2020
  • Uncategorized

It shouldn't happen, but every bit oft, it can yet happen. Sometimes SSL certificates aren't created properly. The effect of it can exist a nasty error message like this:

certificate routines:X509_check_private_key:key values mismatch

In my case information technology was reported by nginx with this:

Apr 27 05:30:51 localhost nginx-rc[3120]: nginx: [emerg] SSL_CTX_use_PrivateKey("/etc/nginx-rc/conf.d/my-server.d/server.primal") failed (SSL: mistake:0B080074:x509 certificate routines:X509_check_private_key:fundamental values mismatch)

As you lot tin can see, it is reported every bit "emerg" which means nginx won't be happy virtually this. In my case this problem caused other vhosts to fail as nginx couldn't reload the configuration and thus couldn't reload the new letsencrypt certificates.

Since I was a flake in a rush I simply rebooted the server, just that made it even worse. nginx didn't start at all and I had to wait at the log files a bit closer. Recreating the certificate that wasn't created correctly was all it took, but knowing that you take to do that, is what's catchy.

Go telegram message if a certificate is invalid

If you haven't sent a message to telegram from your command line, check this article: https://www.marcodena.it/blog/telegram-logging-handler-for-python-java-bash/

In short:

  • You lot befriend the botfather
  • You result a control /newbot, enter a name and yous'll get token
  • You commencement a conversation with your bot and employ that chat id in your script

We can use openssl to go the modulus of the fundamental as well as the certificate. They both take to friction match, otherwise the document is all information technology takes. My script is used with runcloud, just just adjust the path in the loop to get it working in your environment:

#!/bin/fustigate TELEGRAM_TOKEN=<token from telegram> TELEGRAM_CHAT_ID=<chat id from telegram>  URL="https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage"  shopt -s globstar  for keyFile in /etc/nginx-rc/conf.d/*/server.key; do    crtFile="${keyFile::-three}crt"    keyFileModulus=$(openssl x509 -noout -modulus -in $crtFile)    crtFileModulus=$(openssl rsa -noout -modulus -in $keyFile)    if [ "$crtFileModulus" != "$keyFileModulus" ]; then       gyre -s -X POST $URL -d chat_id=$TELEGRAM_CHAT_ID -d text="SSL document is invalid, recreate $keyFile" > /dev/nothing    fi washed



Working with queues in concrete5

  • 19.02.2017
  • Concrete5

A queue can be rather useful when y'all want to process a lot of information, simply also when I just want to make sure things react quickly. Let'southward have a look at a simple instance where you lot might want to send an e-mail.

In a lot of cases people send east-mails right in a controller action. This is okay for a lot of sites, simply sometimes if things are mission critical it helps to use a queue. Imagine what happens if there'southward a temporary problem with the mail system, since you're sending it right in your controller you'll probably prove the user an fault bulletin telling him that something went wrong. Seeing errors is hardly ever a adept thing, with a queue yous could use a simple performance to put the activeness in a queue and procedure it later. If it fails you could try over again a bit later and if information technology fails permanently put information technology in a log file you're monitoring.

There might too exist a maintenance task that y'all tin can finish earlier PHP times out. Using a queue would make information technology more than solid, put every object you want to process in a queue and process it piece past piece.

Putting things in the queue

It's fairly elementary to put things the queue. All you need is a queue name to ensure yous can keep your tasks apart and the information you need subsequently to process the item from the queue:

                  employ                  Physical\Core\Foundation\Queue\Queue;                  $queue                  =                  Queue::                  get                  (                  'queue-demo'                  )                  ;                  $queue                  ->                  send                  (                  i                  )                  ;                

utilise Concrete\Core\Foundation\Queue\Queue; $queue = Queue::go('queue-demo'); $queue->ship(1);

With this we are putting the number 1 in a queue called "queue-demo". Now that nosotros take objects in our queue we need to process them.

Processing queue

When processing a queue we apparently have to use the same queue proper noun.

                  use                  Concrete\Cadre\Foundation\Queue\Queue;                  $queue                  =                  Queue::                  get                  (                  'queue-demo'                  )                  ;                  $queueMessages                  =                  $queue                  ->                  receive                  (                  10                  )                  ;                  foreach                  (                  $queueMessages                  as                  $msg                  )                  {                  $userId                  =                  $msg                  ->                  body                  ;                  // load the object for the user ID and process it                  $queue                  ->                  deleteMessage                  (                  $msg                  )                  ;                  }                

use Concrete\Core\Foundation\Queue\Queue; $queue = Queue::get('queue-demo'); $queueMessages = $queue->receive(10); foreach ($queueMessages equally $msg) { $userId = $msg->torso; // load the object for the user ID and procedure it $queue->deleteMessage($msg); }

That's basically all you need to do, but y'all'll of course demand to put that lawmaking somewhere.

concrete5 has an like shooting fish in a barrel to extend CLI API. You derive a class from "Symfony\Component\Console\Command\Command", implement the "execute" method and handle your queue there. Once you register your command, you tin can access it by running "./concrete/bin/concrete5"
Y'all can find a complete example here: https://github.com/Remo/concrete5-queue-demo. Here are some of the relevant lines:

  • Annals CLI control in controller
  • Configure command, the proper name is what y'all'll specify when running the command
  • Locking and unlocking process. Helps to ensure the command is only running in one case.
  • Getting items from queue and looping through them

You'll just have to run your command regularly to execute it, a cronjob like this should do the fox: "./concrete/bin/concrete5 queue-demo:process-notifications".

There's also a way to handle everything in a task which is peculiarly useful for maintenance tasks as information technology doesn't require that yous add queue items initiaited by a user action. There's a skilful article in the official documentation most this: https://documentation.concrete5.org/developers/jobs/creating-and-scheduling-a-queueable-job.

Benefits

  • Not-blocking executing of tasks
  • Avoid timeouts when treatment a lot of data

Disadvantages

  • Adds a flake more complication to your code
  • concrete5 queues require polling on the executing side, calculation a delay to your task. Deosn't apply to queues in full general, if you employ something like beanstalk y'all can procedure tasks immediately

Some of the code was written by Michele Locati. Hope yous enjoy working with queues!




Group Markers in Google Map with Gmaps Marking Clusterer

  • 07.12.2016
  • JavaScript

If y'all take a map with a lot of markers you'll eventually accept a hard fourth dimension to see all the maps, specially if you zoom out. At that place's a google library called "Js Marker Clusterer" which helps out, information technology simply builds clusters of markers close together. Unfortunately information technology'south not maintained anymore, simply there aren't many good alternatives. That's why we've decided to join our effort and create a fork under a new system. Nosotros couldn't use the same name but wanted to stay close to it's original name. Because of that we've decided to go with Gmaps Marker Clusterer. Information technology'south an attempt to avoid having too many forks which eventually die because of missing interest. Right now nosotros are two contributors, simply we are obviously interested in getting more assist. Yous tin can discover the github page here https://github.com/gmaps-marker-clusterer/gmaps-marker-clusterer and the documentation (work in progress) here: https://gmaps-marker-clusterer.github.io/gmaps-marker-clusterer/

Here'southward a simple example showing y'all how to create a google map with clusters. Information technology assumes you have a global array called "information", information technology can be found here https://gmaps-marker-clusterer.github.io/gmaps-marking-clusterer/assets/js/data.json:

                  var                  markers                  =                  [                  ]                  ;                  for                  (                  var                  i                  =                  0                  ;                  i                  <                  100                  ;                  i++                  )                  {                  var                  dataPhoto                  =                  data.photos                  [i]                  ;                  var                  latLng                  =                  new                  google.maps.LatLng                  (dataPhoto.latitude                  ,                  dataPhoto.longitude                  )                  ;                  var                  marker                  =                  new                  google.maps.Marker                  (                  {                  position:                  latLng                  }                  )                  ;                  markers.push button                  (marker)                  ;                  }                  var                  options                  =                  {                  imagePath:                  'https://raw.githubusercontent.com/gmaps-marker-clusterer/gmaps-marker-clusterer/master/images/chiliad'                  }                  ;                  var                  markerCluster                  =                  new                  MarkerClusterer(map,                  markers,                  options)                  ;                

var markers = []; for (var i = 0; i < 100; i++) { var dataPhoto = data.photos[i]; var latLng = new google.maps.LatLng(dataPhoto.latitude, dataPhoto.longitude); var marker = new google.maps.Marker({ position: latLng }); markers.push(mark); } var options = { imagePath: 'https://raw.githubusercontent.com/gmaps-mark-clusterer/gmaps-marker-clusterer/primary/images/1000' }; var markerCluster = new MarkerClusterer(map, markers, options);

As you can see nosotros basically just create our markers through MarkerClusterer and this will then add all of them in a nice mode to the already existing map object. A complete example with google maps (you might have to set your own fundamental subsequently &key=) would and then look like this:

<style type="text/css"> #map {     width: 600px;     height: 400px;     max-width: 100%; } </style>   <div id="map-container"><div id="map"></div></div> <script>     office initialize() {         var center = new google.maps.LatLng(51.5074, 0.1278);           var map = new google.maps.Map(document.getElementById('map'), {           zoom: iii,           center: center,           mapTypeId: google.maps.MapTypeId.ROADMAP         });           var markers = [];         for (var i = 0; i < 100; i++) {           var dataPhoto = data.photos[i];           var latLng = new google.maps.LatLng(dataPhoto.latitude,               dataPhoto.longitude);           var marking = new google.maps.Marker({             position: latLng           });           markers.push(marker);         }           var options = {             imagePath: 'https://gmaps-mark-clusterer.github.io/gmaps-marking-clusterer/assets/images/grand'         };           var markerCluster = new MarkerClusterer(map, markers, options);     } </script>   <script src="markerclusterer.js"></script> <script src="information.json"></script> <script async defer src="https://maps.googleapis.com/maps/api/js?callback=initialize&key="></script>

<way type="text/css"> #map { width: 600px; summit: 400px; max-width: 100%; } </manner> <div id="map-container"><div id="map"></div></div> <script> part initialize() { var center = new google.maps.LatLng(51.5074, 0.1278); var map = new google.maps.Map(certificate.getElementById('map'), { zoom: 3, center: eye, mapTypeId: google.maps.MapTypeId.ROADMAP }); var markers = []; for (var i = 0; i < 100; i++) { var dataPhoto = data.photos[i]; var latLng = new google.maps.LatLng(dataPhoto.latitude, dataPhoto.longitude); var marker = new google.maps.Marker({ position: latLng }); markers.push(mark); } var options = { imagePath: 'https://gmaps-marker-clusterer.github.io/gmaps-marker-clusterer/assets/images/m' }; var markerCluster = new MarkerClusterer(map, markers, options); } </script> <script src="markerclusterer.js"></script> <script src="data.json"></script> <script async defer src="https://maps.googleapis.com/maps/api/js?callback=initialize&key="></script>

Y'all can observe a working example here https://gmaps-marker-clusterer.github.io/gmaps-marker-clusterer/instance-simple/. A real life case can exist found hither, a Swiss site showing you interesting places to spend your fourth dimension in the nature with your kids, playgrounds, fireplaces and more than: https://www.freizeitplatz.ch/




VueJS2 UI exam – Quasar Framework

  • 25.x.2016
  • JavaScript, Vue.JS

Later I published my article most VueStrap things take changed a bit. We at present have the awesome version 2 of VueJS and patently we demand to build a UI with it at some point. I took that as a reason to have some other look at the UI libraries.

I was able to find a few frameworks for VueJS2. I managed to observe three and had a quick await at all of them

  • http://vuikit.github.io/vuikit/ Experience clean and simple. Button checkboxes where only the button border changes feels a fleck too subtle to me, just overall information technology looks pretty good.
  • http://quasar-framework.org/ Seems to take a focus on mobile devices, just works on a desktop too. Extensive documentation, dandy starting time impression.
  • http://element.eleme.io/ Unfortunately this is only in Chinese, but some parts are in two languages, that's adept plenty to notice the component you need. Looks pretty solid too, but seems to have less components than Quasar.

I've decided to give Quasar a become equally information technology feels very complete and solid.

Getting started with Quasar Framework.

In that location'due south not much to explain, the documentation is up to date and easy to understand. If you need more details, apply the author's documentation: http://quasar-framework.org/guide/index.html

Here's what I did:

npm                  install                  -g                  quasar-cli quasar init quasar-test                  cd                  quasar-examination npm                  install                

npm install -m quasar-cli quasar init quasar-exam cd quasar-examination npm install

No problem in that location, everything installed fine. Information technology seems similar in that location are two different themes. The default material theme:

A second i called iOS

Allow's run across how it looks:

quasar

Crawly, textile and iOS style in a second!

Adding a new Quasar framework component

The commencement screen is made of the index.vue establish in src/components. Let'south try to add a fixed button like shown here: http://quasar-framework.org/components/floating-action-buttons.html

When I tried to remove the logo I received an error:

chrome_2016-10-25_09-49-03

How awesome is this, information technology helps me to write nicely formatted code and fifty-fifty tells me right in the browser with live reload. Let's remove the trailing spaces and requite it some other try. Spaces removed and it works, no issues at all!

I similar tree, the dark-green ones, but besides the ones on my screen. Let'due south have a wait at the documentation: http://quasar-framework.org/components/tree.html

Copy the model information to our alphabetize.vue and add the element to the template. Again, everything works smoothly:

chrome_2016-10-25_09-53-48

I'm impressed with Quasar Framework! The outset impression lasts! I played effectually with a few more things and whatever I practise work well. There'south fifty-fifty a live reload plugin for Android. All those features at this quality is amazing.




Vue.JS UI Exam / VueStrap

I recently became quite fond of Vue.JS. It feels like a simpler version of AngularJS i / Angular 2 and so far came with everything I was looking for. It took me a while to get everything up and running, npm with all its dependencies, multiple versions and more alpha than beta libraries it tin exist a bit annoying, but once things are running smoothen, it's quite job. Naturally I need to have some kind of graphical interface.

In that location's a smashing listing of Vue.JS libraries, ever a good start if you need something: https://github.com/vuejs/crawly-vue

As I'm pretty experiences with bootstrap, I just felt that I should get with something not completely new to me. With currently 2364 stars and a lot of activity merely a few hours ago the projection seems to be very much alive. I was too happy to run into 45 different contributors, the bulk of the piece of work done by fewer people though. Here'south the project's home: https://github.com/yuche/vue-strap.

Getting started

First nosotros accept to create a Vue.JS project. Bold yous've got node and npm installed, yous tin install the vue-cli tools to do that:

In one case you've got that installed, y'all tin can create a simple project past running this control:

vue init webpack-elementary#one.0 vue-strap-test                

vue init webpack-simple#ane.0 vue-strap-test

Delight note that I've specify version 1 as version 2 isn't stable yet. Once the project has been created we have to install the npm modules.

                  cd                  vue-strap-test npm                  install                

cd vue-strap-exam npm install

At present that nosotros've got our empty Vue.JS project nosotros have to add VueStrap. Nosotros can easily exercise that by running this command

npm                  install                  vue-strap bootstrap fashion-loader

npm install vue-strap bootstrap style-loader

Please note that I'g also installed bootstrap as nosotros require its CSS and style-loader and then that we tin hands embed bootstrap from our component. More about that later.

Everything is installed, let's open src/App.vue and add our components. First we add together something to the template section, right after the h1 element:

<alert type="success">    Success! </warning>

<alert type="success"> Success! </alert>

In the script section we also take to import two files, our VueStrap component and of grade bootstrap:

                  import                  {                  warning                  }                  from                  'vue-strap'                  import                  'bootstrap/dist/css/bootstrap.css'                

import { alert } from 'vue-strap' import 'bootstrap/dist/css/bootstrap.css'

And and then nosotros as well demand to brand the imported component available by adding these lines:

The consummate component looks similar the file shown hither https://github.com/ortic/vue.js-ui-test/blob/master/vue-strap-test/src/App.vue

If y'all then go back to your terminal, yous can simply blazon npm run dev so open your browser at http://localhost:8080
The squeamish thing about running dev is that it automatically reload if y'all alter your code. Hither are two more changes to the component to add together more bootstrap features:

  • https://github.com/ortic/vue.js-ui-examination/commit/46d553b084eac20fff12788f4369973fd01318bf
  • https://github.com/ortic/vue.js-ui-examination/commit/609ee8bee2e7e93683364459163b6e9f1a4e28c5

If everything worked, y'all should some something similar this:

chrome_2016-09-20_17-19-45

Determination about VueStrap

Existence Bootstrap makes information technology rather powerful and very familiar to lots of developers, that's certainly a big plus. I somehow like that they implemented the whole JavaScript office using Vue.JS, that makes it lighter and more Vue.JS similar, but reinventing this part might crusade some new bugs to evidence up also. It seems like at that place are still a few bugs which I can find in very piddling time. My first attempt with browserify on tiptop of an existing projection lead me to this trouble. https://github.com/yuche/vue-strap/issues/198. In this attempt, the popover component didn't seem to work. The DOM gets inverse, merely the CSS holding display is nevertheless prepare to none, here's the commit https://github.com/ortic/vue.js-ui-test/commit/a3fab52f9195d90995ada87d3e031a30575888ea.

While it seems to be pretty cool, I'm not convinced it's stable plenty to be used in a big calibration project unless yous're okay with fixing a few things yourself. It'southward costless afterwards all and the code isn't too difficult to sympathize once yous've got a hang of Vue.JS. I'll keep on testing other frameworks to narrow things a bit down.




concrete5.seven – Custom Toolbar Button

  • 21.12.2015
  • Concrete5

concrete5 had an API to add together a custom button to the inline editing toolbar. Here'south the commodity for the older five.half-dozen version: http://www.codeblog.ch/2012/04/concrete5-custom-toolbar-button/

In 5.7 a few things take inverse. The thought is notwithstanding the same, but you'll have to apply namespaces and loading classes is a bit different too.

Here's how to get access to the menu helper:

1                      
                        $menuHelper                        =                        Core::                        make                        (                        'helper/physical/ui/bill of fare'                        )                        ;                      

$menuHelper = Core::make('helper/concrete/ui/bill of fare');

You lot then have to call the addPageHeaderMenuItem method. Assuming you've already got a bundle, this is how the on_start method could wait like:

ane 2 3 4 five six seven 8 nine 10 11 12 xiii 14 15 sixteen 17 18                      
                        public                        function                        on_start(                        )                        {                        $req                        =                        \Asking::                        getInstance                        (                        )                        ;                        // Make sure we don't inject our lawmaking if it'due south chosen by an AJAX request                        if                        (                        !                        $req                        ->                        isXmlHttpRequest                        (                        )                        )                        {                        /* @var $menuHelper \Physical\Core\Application\Service\UserInterface\Menu */                        $menuHelper                        =                        Core::                        brand                        (                        'helper/concrete/ui/menu'                        )                        ;                        $menuHelper                        ->                        addPageHeaderMenuItem                        (                        'ortic_btn'                        ,                        $this                        ->                        pkgHandle                        ,                        array                        (                        'icon'                        =>                        'question'                        ,                        'label'                        =>                        t(                        'Ortic'                        )                        ,                        'position'                        =>                        'correct'                        ,                        'href'                        =>                        'http://world wide web.ortic.com'                        ,                        'linkAttributes'                        =>                        array                        (                        'id'                        =>                        'ortic-push'                        ,                        'target'                        =>                        '_blank'                        )                        )                        )                        ;                        }                        }                      

public function on_start() { $req = \Request::getInstance(); // Make certain we don't inject our lawmaking if information technology's called by an AJAX request if (!$req->isXmlHttpRequest()) { /* @var $menuHelper \Concrete\Core\Application\Service\UserInterface\Menu */ $menuHelper = Core::make('helper/concrete/ui/menu'); $menuHelper->addPageHeaderMenuItem('ortic_btn', $this->pkgHandle, array( 'icon' => 'question', 'label' => t('Ortic'), 'position' => 'right', 'href' => 'http://www.ortic.com', 'linkAttributes' => assortment('id' => 'ortic-button', 'target' => '_blank') )); } }

Delight note that nosotros're checking if the request is handled by an AJAX asking. This can help to avert collisions if y'all inject more things.

After that you'll simply have to create one more file in your package. Within "menu_items", create a new folder with the button name, in my case "ortic_btn" (the first argument of addPageHeaderMenuItem ) and add a content like this:

1 2 iii 4 5 half-dozen 7 eight ix x eleven 12 13 xiv                      
                        <?php                        namespace                        Physical\Package\OrticToolbar\MenuItem\OrticBtn;                        class                        Controller                        extends                        \Concrete\Cadre\Awarding\UserInterface\Carte du jour\Item\Controller                        {                        /**      * Return false if you don't want to display the button      * @render bool      */                        public                        function                        displayItem(                        )                        {                        render                        true                        ;                        }                        }                      

<?php namespace Concrete\Parcel\OrticToolbar\MenuItem\OrticBtn; class Controller extends \Concrete\Core\Application\UserInterface\Carte\Item\Controller { /** * Return false if you don't desire to display the button * @return bool */ public function displayItem() { return true; } }

Please note that "OrticToolbar" refers to my package.

You lot tin can observe the complete case on github: https://github.com/ortic/ortic-button




concrete5.7 Open Source Packages

  • 15.06.2015
  • Concrete5

concrete5 version 5.seven is out for a couple of calendar month and as always with a major version, old stuff might is cleaved and it takes a while to find new packages, resources and information. I tried to assemble a listing of open up source packages for 5.7 which you can use in your project or learn from to build your own packages. Please note that some packages aren't stable yet, it'due south not a listing for terminate-users but rather a listing for concrete5 developers eager to learn about building add-ons.

Please let me know if I accept missed a package, I'll happily update my list.

Bundle URL Clarification
Add Multiple Pages https://github.com/Mesuva/add_multiple_pages Dashboard extension to add multiple pages in i go
Redactor anchors plugin https://github.com/csebe/anchors_redactor_plugin Redactor plugin to create anchors inside the edited text
Attribute Forms https://github.com/Remo/concrete5-attribute-forms Create forms usings attributes to get more than flexibility, work in progress
Sound Histrion https://github.com/cpill0789/HTML5-Audio-Histrion-Basic Audio player
C5 Downloader https://github.com/tao-s/c5downloader Script to download and install concrete5
Cal Packet https://github.com/olsgreen/cal_package Agenda functionality
CKEditor https://github.com/Mesuva/ckeditor_content Inline editor using CKEditor, doesn't integrate file manager
CSV XML Converter https://github.com/hissy/addon_csv_xml_converter Create an XML file based on a CSV input y'all can import to your concrete5
site
Designer Content 5.7 https://github.com/concrete5japan/c5_designer_content_57 Create blocks for concrete5 using a visual interface
Programmer Tools https://github.com/ExchangeCore/concrete5-Developer-Tools Developer Tools
Epicblue https://github.com/caomicc/Epicblue concrete5 theme
Fotorama Gallery https://github.com/olsgreen/fotorama_package Adds a block using the Fotorama gallery script
Foundation Sites https://github.com/core77/foundation_sites Package containing a theme and various block templates using foundation
Handsontable https://github.com/Mesuva/msv_table Inline block using Handsontable to create tables using an excel similar
interface
LDAP Login https://github.com/go2sh/concrete5-ldap-login Package extending the hallmark organization
Lits files https://github.com/Mesuva/list_files_from_set Lists files from a file set
Mai Chimp https://github.com/core77/mail_chimp Block that let's you signup to mailchimp newsletter lists
Transmission NAV https://github.com/concrete5japan/Transmission-Nav Build a navigation by manually assembling your pages
Multilingual Global Surface area https://github.com/hissy/addon_multilingual_global_area Makes global area global per language
Open up Graph Tags https://github.com/hissy/c5-open-graph-tags-lite Add open graph tags to your site
Package Installer https://github.com/Remo/concrete5-bundle-installer Allows you to upload a Null file containing a package to exist instaled
Farsi Payment for VividStore https://github.com/Shayan66/parsian_payment_vividstore Persian Payment for VividStore
Plainly Text Attribute https://github.com/Remo/concrete5-attribute-apparently-text Attribute to add static text, useful in combination with attribute forms
QR Code https://github.com/Remo/concrete5-qr-code Block to embed QR code in your website
Razor Commere https://github.com/RazorCommerce/razor-commerce/ An east-commerce solution
Sakan https://github.com/concrete5japan/sakan theme based on bootstrap 3
Snowfall Migrate https://github.com/mkly/Snow-Migrate concrete5 theme
Social Share https://github.com/hissy/c5_social_share_lite Adds share icons to your site
End Forum SPAM https://github.com/ExchangeCore/Concrete5-Stop-Forum-Spam SPAM protection add-on
SVG Prototype https://github.com/Mesuva/svg_image SVG image with a bitmap fallback
Tweet Feed https://github.com/olsgreen/tweet_feed_package Adds a twitter feed to your site
Under Construction https://github.com/mkly/Under-Construction Adds an under construction page
Vanity URLs https://github.com/mkly/Vanity-Urls Allow'southward yous admission user profile pages using /@username
Vivid Shop https://github.com/VividWeb/vivid_store An east-commerce solution



concrete5.7 upgrade packages

Every bit you might have heard, a major release of concrete5 has been published. If you haven't, here'south a listing of things that have changed http://world wide web.concrete5.org/documentation/background/version_history/5-seven-0/.

In this post, I'm going to look at the process of upgrading an existing package which worked for version 5.six. I'1000 doing this step by pace to evidence to prove you lot possible fault messages which might assist you lot catechumen y'all ain packages, merely delight note that I'one thousand aiming at concrete5 developers knowing version five.6 and will thus skip a few things which haven't changed.

I'thou going to use a unproblematic package I wrote a while ago, it'due south the zoom image block which allows you lot to zoom into a single image. Much similar lightbox, simply limited to a single motion picture. The code tin be institute here https://github.com/Remo/concrete5-zoom-image.

The Directory Construction of concrete5.7

Once you lot've downloaded and installed concrete5.7 you lot'll probably see that the directory construction has inverse quite a bit:
concrete5.7 directory structure

  • The root directory
    • There are only four directories left
    • application – this is where your overrides for your own site should exist placed
    • physical – this is still the core and should never be touched unless
    • packages – this is patently the place where you have to add your own packages
    • updates – still the aforementioned, here's where you tin can find an updated cadre
  • What new directories are there
    • hallmark – at that place'southward a pretty neat authentication organization y'all can extend, by default at that place's a born concrete5 organisation and 1 supporting facebook
    • bootstrap – as the name tells you, hither's where things get started, loaded etc.
    • src – this is where y'all can find the PSR4 auto-loaded classes, accept a look at this directory to get acquainted with the new things in concrete5
    • vendor – version v.7 partially uses composer.json to manage dependencies, this is where yous can find the libraries installed past composer

Installing the zoom epitome bundle

Before you install anything, make certain you've got a database dump y'all tin easily restore, it might make things easier.

I just downloaded the latest version from github and placed it in a directory called zoom_image in the packages directory. In concrete5, type add functionality in the search box and select the first particular. You'll already see your get-go exception at this signal:

concrete5.7 exception.

We can't see any details about the mistake, now what? You tin either expect at your database and check the content of the Logs table or become dorsum and type debug in the search box. Navigate to debug settings and check Bear witness errors in page.. If you so to back to install your package, you'll see a nice output produces by https://github.com/filp/whoops. It tells use, that we can't redeclare the course ZoomImagePackage. That'due south because concrete5.vii uses namespaces for pretty much everything. To get around this problem, we have to update the controller in our package. The first few lines take to expect like this:

1 2 three 4 5 6 vii 8 ix 10 eleven                      
                        <?php                        namespace                        Concrete\Parcel\ZoomImage;                        defined                        (                        'C5_EXECUTE'                        )                        or                        die                        (                        'Access Denied.'                        )                        ;                        grade                        Controller                        extends                        \Concrete\Core\Package\Package                        {                        protected                        $pkgHandle                        =                        'zoom_image'                        ;                        protected                        $appVersionRequired                        =                        '5.seven.0'                        ;                        protected                        $pkgVersion                        =                        'two.0.0'                        ;                      

<?php namespace Physical\Parcel\ZoomImage; defined('C5_EXECUTE') or dice('Access Denied.'); class Controller extends \Physical\Cadre\Package\Bundle { protected $pkgHandle = 'zoom_image'; protected $appVersionRequired = 'v.seven.0'; protected $pkgVersion = 'two.0.0';

  • A package controller class is e'er called Controller.
  • It derives from \Concrete\Core\Packet\Bundle
  • The namespace of your package controller has to start with Concrete\Package\ and must then be suspend with the camelcased name of your bundle.
  • I also updated the number to exist two.0.0, that's not necessary, but probably brand sense

When you reload the add together functionality page again, yous'll finally encounter our package. Let's try and install it! Next error:
Class 'Concrete\Package\ZoomImage\BlockType' non found. As I've mentioned above, the src directory contains some rather useful classes. We're looking for something related to blocks and no surprise, there's a Block directory. If you lot await at src/Block/BlockType/BlockType.php you lot can see where the missing grade is. Open the file and y'all'll know the namespace we accept to import.

1 two 3 iv 5                      
                        <?php                        namespace                        Concrete\Package\ZoomImage;                        use                        Concrete\Core\Block\BlockType\BlockType;                      

<?php namespace Concrete\Package\ZoomImage; use Concrete\Core\Cake\BlockType\BlockType;

Unfortunately the parcel got installed anyhow and uninstalling can be tricky if parts of your code haven't been upgraded for 5.vii. Allow'southward but restore that dump file we've created and attempt to install the package once more. Guess what, the adjacent exception. The zoom image block uses an one-time out-dated method called Loader::block. Remove it, restore the dump file and try once more. Adjacent, you'll get an exception because BlockController isn't defined. Namespaces again! While we practise this, we can too make the grade name change like nosotros did with the package controller.

  • The class is simply called Controller too.
  • You'll take to derive it from \Concrete\Cadre\Block\BlockController. If you expect at the code below, you can come across that I didn't specify the fully qualifier proper name when deriving the grade but rather added some other statement to use.
  • Your namespace has to be Concrete\Package\[camel-example-package-handle]\Block\[camel-case-cake-handle]

After making these changes, restore the dump file and install the package again – the installation procedure works! Now permit'south endeavour to add together a zoom image cake. Become back to the website and hitting the plus icon:

concrete5.7 add block

Drag your block into the folio and release it. The cake interface shows up, but after adding the block, nix happens. That'southward considering the AJAX magic hid the fault message, reload the page and you'll get your next exception to work with Course 'Concrete\Package\ZoomImage\Block\ZoomImage\File' not plant. As you lot tin can see, information technology tries to load the grade File in our own namespace where it can't be constitute. We forgot to add another use statement. Let'south add \Concrete\Core\File\File and reload the page.

We now get the message Call to a member function getFileObject() on a non-object.

concrete5.7 exception 2

Accessing the controller from view.php was a bit of a habit when you looked at code back from version 5.0 and a bit later. Before we worry about the message, let'south make sure we properly forwards data from the controller to the view and not the other way round.

Permit's add the following method to the cake controller:

one two three four 5 6 7 8 ix 10 11                      
                        public                        role                        view(                        )                        {                        $ih                        =                        Loader::                        helper                        (                        'image'                        )                        ;                        $fileObject                        =                        $this                        ->                        getFileObject                        (                        )                        ;                        $fileName                        =                        $fileObject                        ->                        getRelativePath                        (                        )                        ;                        $thumbnail                        =                        $ih                        ->                        getThumbnail                        (                        $fileObject                        ,                        intval                        (                        $this                        ->                        thumbnailWidth                        )                        ,                        intval                        (                        $this                        ->                        thumbnailHeight                        )                        )                        ;                        $this                        ->                        set                        (                        'fileName'                        ,                        $fileName                        )                        ;                        $this                        ->                        fix                        (                        'thumbnail'                        ,                        $thumbnail                        )                        ;                        }                      

public function view() { $ih = Loader::helper('image'); $fileObject = $this->getFileObject(); $fileName = $fileObject->getRelativePath(); $thumbnail = $ih->getThumbnail($fileObject, intval($this->thumbnailWidth), intval($this->thumbnailHeight)); $this->set('fileName', $fileName); $this->ready('thumbnail', $thumbnail); }

Use those variables in your view.php and and then endeavour to reload the folio. No fault messages for a alter, but when you publish the folio changes and try to click on the thumbnail of your block, nothing happens. If we cheque the mistake panel of the browser, we can run across a problem due to undefined jQuery variables. At the time when our javascript gets executed, jQuery isn't loaded. We don't call back too much about information technology and only utilise addFooterItem instead of addHeaderItem.

Reload and nonetheless no luck, msie isn't defined. But luckily that's just because of our JavaScript which isn't happy with the new jQuery version. Update the script to get around that.

That's it! JavaScript fixed and no more bug, everything working! While this commodity is a scrap long, what we really did isn't that much. In short:

  • Namespaced all of our controllers, the bundle and block controller
  • Fabricated sure we properly forwarded our variables from the controller to the view (something I should have done before)
  • Fixed a trouble because of the new jQuery version in concrete5.vii

You lot can find the commit I've made on github, a proper unequal file might assist https://github.com/Remo/concrete5-zoom-epitome/commit/fa0895081b62fbbb53d8e79c00858619fcec1fd4.

Take fun with v.7!




Floating Point Arithmetic in MySQL

  • 01.09.2014
  • SQL

The fact that computers aren't perfect at calculation is something well-nigh developers know. 1/3 can't be saved equally a floating point number, information technology would be infinitely long, 0.3333… If you lot aren't aware of that, bank check out this site, it explains the problem quite nicely http://floating-point-gui.de/.

About people who piece of work with SQL rarely come across this trouble, but in that location's one pitfall which in my opinion is fifty-fifty more dangerous, especially since SQL handles this problem in well-nigh cases quite well.

Let'southward start by creating a dummy table and insert a row with two numbers:

                  Drib                  TABLE                  IF                  EXISTS                  mathtest;                  CREATE                  Table                  mathtest                  (num_dec                  DECIMAL                  (                  20                  ,                  x                  )                  ,                  num_float                  Float                  );                  INSERT                  INTO                  mathtest                  VALUES                  (                  2018.446510036496                  ,                  2018.446510036496                  );

drop tabular array if exists mathtest; create table mathtest (num_dec decimal(20, 10), num_float float); insert into mathtest values (2018.446510036496, 2018.446510036496);

Now that we have some data to piece of work with, let's query our tabular array and add together two columns with a static value.

                  SELECT                  circular(num_float,                  9                  )                  table_float,                  round(num_dec,                  9                  )                  table_decimal,                  round(                  2018.446510036496                  ,                  ix                  )                  static_float,                  round(                  CAST                  (                  2018.446510036496                  Every bit                  DECIMAL                  (                  20                  ,                  ten                  )                  )                  ,                  9                  )                  static_decimal                  FROM                  mathtest;

select round(num_float, 9) table_float, round(num_dec, 9) table_decimal, circular(2018.446510036496, 9) static_float, round(bandage(2018.446510036496 as decimal(twenty,10)), 9) static_decimal from mathtest;

What volition the consequence be of this? The kickoff table_float is pretty obvious, it'southward very imprecise, but what nearly the others? Allow's take a look:

Table Float 2018.446533203
Table Decimal 2018.446510037
Static Float 2018.446510036
Static Decimal 2018.446510037

What does this tell us? It'south unproblematic, when you query data from a tabular array, it will use the precision of the column blazon. Only when you practise some arithmetic in an SQL query, it will utilise floats by default and thus be imprecise. If nosotros cast information technology to a decimal, we can get a precision of 64 digits.

Not a big deal, but make sure yous're aware how you lot do your calculations in SQL!




concrete5 – Working with custom Permission Keys

When you build an add together-on with concrete5, you'll sometimes desire to hide a few things depending on the users or group. You might exist tempted to hard-code a cheque to a specific grouping, but there'southward a much more than elegant style to handle this. Information technology likewise gives y'all a lot more ability to control who's immune to practise something, simply in case your client changes.

In this tutorial, nosotros're edifice a new package called "codeblog_task_permissions" which you have to put in your "packages" directory. Inside the new package directory, create a new file called "controller.php" and put the following content in it, we'll take a closer look at what it does afterwards:

1 ii three iv 5 6 7 viii 9 ten 11 12 thirteen 14 xv 16 17 xviii 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 xl 41 42 43 44 45 46 47 48 49 l                      
                        <?php                        class                        TaskPermissionsPackage                        extends                        Package                        {                        protected                        $pkgHandle                        =                        'task_permissions'                        ;                        protected                        $appVersionRequired                        =                        '5.6.three'                        ;                        protected                        $pkgVersion                        =                        'i.0'                        ;                        public                        role                        getPackageDescription(                        )                        {                        return                        t(                        "Installs the Chore Permission demo package."                        )                        ;                        }                        public                        function                        getPackageName(                        )                        {                        render                        t(                        "Task Permissions"                        )                        ;                        }                        public                        function                        install(                        )                        {                        $pkg                        =                        parent::                        install                        (                        )                        ;                        $this                        ->                        installTaskPermissions                        (                        $pkg                        )                        ;                        }                        /**      * This method installs our permission keys      *       * @param Package $pkg      */                        protected                        function                        installTaskPermissions(                        $pkg                        )                        {                        // add a new permission key to handle shutdons                        $pkShutdownHandle                        =                        'shutdown_planet'                        ;                        if                        (                        !                        is_object                        (PermissionKey::                        getByHandle                        (                        $pkShutdownHandle                        )                        )                        )                        {                        $pkShutdown                        =                        PermissionKey::                        add                        (                        'admin'                        ,                        $pkShutdownHandle                        ,                        t(                        'Shutdown the planet'                        )                        ,                        t(                        'Permission to shutdown the planet'                        )                        ,                        ''                        ,                        ''                        ,                        $pkg                        )                        ;                        // assign administrators the right to handle our planet                        $grouping                        =                        Grouping::                        getByID                        (ADMIN_GROUP_ID)                        ;                        $adminGroupEntity                        =                        GroupPermissionAccessEntity::                        getOrCreate                        (                        $group                        )                        ;                        $pa                        =                        PermissionAccess::                        create                        (                        $pkShutdown                        )                        ;                        $pa                        ->                        addListItem                        (                        $adminGroupEntity                        )                        ;                        $pt                        =                        $pkShutdown                        ->                        getPermissionAssignmentObject                        (                        )                        ;                        $pt                        ->                        assignPermissionAccess                        (                        $pa                        )                        ;                        }                        // install a second permission fundamental to control the weather                        $pkWeatherHandle                        =                        'make_weather_nice'                        ;                        if                        (                        !                        is_object                        (PermissionKey::                        getByHandle                        (                        $pkWeatherHandle                        )                        )                        )                        {                        $pkWeather                        =                        PermissionKey::                        add together                        (                        'admin'                        ,                        $pkWeatherHandle                        ,                        t(                        'Remote Weather Command'                        )                        ,                        t(                        'Access to the remote weather control system'                        )                        ,                        ''                        ,                        ''                        ,                        $pkg                        )                        ;                        }                        }                        }                      

<?php class TaskPermissionsPackage extends Parcel { protected $pkgHandle = 'task_permissions'; protected $appVersionRequired = '5.6.3'; protected $pkgVersion = 'i.0'; public function getPackageDescription() { return t("Installs the Task Permission demo packet."); } public function getPackageName() { return t("Task Permissions"); } public function install() { $pkg = parent::install(); $this->installTaskPermissions($pkg); } /** * This method installs our permission keys * * @param Package $pkg */ protected function installTaskPermissions($pkg) { // add a new permission primal to handle shutdons $pkShutdownHandle = 'shutdown_planet'; if (!is_object(PermissionKey::getByHandle($pkShutdownHandle))) { $pkShutdown = PermissionKey::add('admin', $pkShutdownHandle, t('Shutdown the planet'), t('Permission to shutdown the planet'), '', '', $pkg); // assign administrators the right to handle our planet $group = Group::getByID(ADMIN_GROUP_ID); $adminGroupEntity = GroupPermissionAccessEntity::getOrCreate($group); $pa = PermissionAccess::create($pkShutdown); $pa->addListItem($adminGroupEntity); $pt = $pkShutdown->getPermissionAssignmentObject(); $pt->assignPermissionAccess($pa); } // install a 2nd permission central to control the atmospheric condition $pkWeatherHandle = 'make_weather_nice'; if (!is_object(PermissionKey::getByHandle($pkWeatherHandle))) { $pkWeather = PermissionKey::add('admin', $pkWeatherHandle, t('Remote Weather Command'), t('Access to the remote weather control system'), '', '', $pkg); } } }

Permit's have a look at the simpler example. In line 44 we're setting the handle of the permission key, it'due south what nosotros demand to piece of work with it when nosotros run our check in the code. In the next line, we cheque if the permission key is already installed, if it isn't, we add together information technology. These are the parameters y'all can use:

                  public                  static                  function                  add together(                  $pkCategoryHandle                  ,                  $pkHandle                  ,                  $pkName                  ,                  $pkDescription                  ,                  $pkCanTriggerWorkflow                  ,                  $pkHasCustomClass                  ,                  $pkg                  =                  false                  )                

public static function add( $pkCategoryHandle, $pkHandle, $pkName, $pkDescription, $pkCanTriggerWorkflow, $pkHasCustomClass, $pkg = false )

That's all we need to add together a custom aspect key. If y'all install the package and navigate to "/dashboard/organization/permissions/tasks/" in your dashboard, you'll see your custom permission keys at the end of the screen.

permissionkeys

As y'all can see, our new permission key doesn't take any groups assigned to it. You tin can either practise that manually, or by code. In the case to a higher place, the beginning permission key shows you how to do that. Just have a await at the lines 33 to twoscore. We get an instance of our administrators grouping and so pass it along a permission access object which we can assign to our permission central.

Now that we have created our permission keys, we want to use them. This part is even easier, all yous have to do is to create a PermissionKey object and run the "can()" method:

i 2 iii 4 five 6                      
                        $pk                        =                        PermissionKey::                        getByHandle                        (                        'shutdown_planet'                        )                        ;                        if                        (                        $pk                        ->                        tin                        (                        )                        )                        {                        echo                        t(                        'Yes you lot are allowed to shutdown the planet'                        )                        ;                        }                        else                        {                        echo                        t(                        'We are pitiful simply yous have no permissions to shutdown the planet'                        )                        ;                        }                      

$pk = PermissionKey::getByHandle('shutdown_planet'); if ($pk->can()) { echo t('Yes you lot are allowed to shutdown the planet'); } else { repeat t('We are sorry but you have no permissions to shutdown the planet'); }

Yous can notice the complete case on github, https://github.com/Remo/codeblog/tree/primary/codeblog_task_permissions. If you use the instance and desire to check the permissions, betoken your browser to http://one/index.php/tools/packages/task_permissions/check_permissions and you'll see atmospheric condition you have the permission to the keys or non.




concrete5 – use LESS files for block templates

If y'all congenital a couple of block templates, y'all'll probably accept had some nasty CSS code. Quite oft yous'll have block specific options, a groundwork color for example, which has to change the CSS file. Yous tin easily exercise that, no doubt, only use addHeaderItem or put a fashion tag in your view.php. The block controller lawmaking might expect like this:

1 two iii                      
                        public                        function                        on_page_view(                        )                        {                        $this                        ->                        addHeaderItem                        (                        '<style type="text/css">#my-block-'                        .                        $this                        ->                        bID                        .                        ' { background: '                        .                        $this                        ->                        backgroundColor                        .                        '; }</style>'                        )                        ;                        }                      

public function on_page_view() { $this->addHeaderItem('<style type="text/css">#my-block-' . $this->bID . ' { background: ' . $this->backgroundColor . '; }</manner>'); }

In most cases you'll find situations where the developer mixed a code like shown above with an external CSS file.

That certainly works but it's normally much more than elegant to proceed all the cake related CSS rules in a unmarried file. Nosotros tin use the great LESS language to achieve a much more elegant solution. Wouldn't it be great if yous could put all the CSS rules in a file like this:

i two 3 iv five 6                      
                        #my-block@{bID}                        {                        background                        :                        @backgroundColor;                        display                        :                        block                        ;                        width                        :                        100px                        ;                        height                        :                        100px                        ;                        }                      

#my-block@{bID} { background: @backgroundColor; display: block; width: 100px; acme: 100px; }

That'south possible, it just takes a bit more than code. You'll demand lessphp bachelor here http://leafo.cyberspace/lessphp/. In your block controller, you can use a method similar this to compile a LESS file like the one shown to a higher place into a static CSS with all variables replaced on the fly if required. Here's the code:

1 2 3 4 5 6 vii 8 9 10 eleven 12 13 fourteen 15 xvi 17 xviii nineteen 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37                      
                        public                        function                        on_page_view(                        )                        {                        // get electric current block template                        $template                        =                        $this                        ->                        getCurrentTemplate                        (                        )                        ;                        $bv                        =                        new                        BlockView(                        )                        ;                        $bv                        ->                        setController                        (                        $this                        )                        ;                        $bv                        ->                        setBlockObject                        (                        $this                        ->                        getBlockObject                        (                        )                        )                        ;                        // build path to less file                        $blockPath                        =                        $bv                        ->                        getBlockPath                        (                        )                        ;                        if                        (                        $template                        ==                        ''                        )                        {                        $blockTemplateLessPath                        =                        $blockPath                        .                        DIRECTORY_SEPARATOR                        .                        'view.less'                        ;                        }                        else                        {                        $blockTemplateLessPath                        =                        $blockPath                        .                        DIRECTORY_SEPARATOR                        .                        'templates'                        .                        DIRECTORY_SEPARATOR                        .                        $template                        .                        DIRECTORY_SEPARATOR                        .                        'view.less'                        ;                        }                        // in that location'due south a less file, check if nosotros have to rebuild it                        if                        (                        file_exists                        (                        $blockTemplateLessPath                        )                        )                        {                        $lessFileHash                        =                        md5                        (                        $blockTemplateLessPath                        .                        $this                        ->                        bID                        .                        filemtime                        (                        $blockTemplateLessPath                        )                        )                        ;                        $cacheFile                        =                        DIR_FILES_CACHE                        .                        '/my-cake-'                        .                        $lessFileHash                        .                        '.css'                        ;                        // enshroud file doesn't exist, rebuild it                        if                        (                        !                        file_exists                        (                        $cacheFile                        )                        )                        {                        $lessc                        =                        Loader::                        library                        (                        '3rdparty/lessc.inc'                        ,                        'my_block'                        )                        ;                        $lessc                        =                        new                        lessc(                        )                        ;                        $lessc                        ->                        setVariables                        (                        assortment                        (                        'backgroundColor'                        =>                        $this                        ->                        backgroundColor                        ,                        'bID'                        =>                        $this                        ->                        bID                        )                        )                        ;                        $lessc                        ->                        compileFile                        (                        $blockTemplateLessPath                        ,                        $cacheFile                        )                        ;                        }                        // include generated css file                        $this                        ->                        addHeaderItem                        (                        '<link rel="stylesheet type="text/css" href="'                        .                        REL_DIR_FILES_CACHE                        .                        '/embrace-motion-picture show-'                        .                        $lessFileHash                        .                        '.css'                        .                        '"/>'                        )                        ;                        }                      

public office on_page_view() { // go current cake template $template = $this->getCurrentTemplate(); $bv = new BlockView(); $bv->setController($this); $bv->setBlockObject($this->getBlockObject()); // build path to less file $blockPath = $bv->getBlockPath(); if ($template == '') { $blockTemplateLessPath = $blockPath . DIRECTORY_SEPARATOR . 'view.less'; } else { $blockTemplateLessPath = $blockPath . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . 'view.less'; } // there'south a less file, check if we accept to rebuild it if (file_exists($blockTemplateLessPath)) { $lessFileHash = md5($blockTemplateLessPath . $this->bID . filemtime($blockTemplateLessPath)); $cacheFile = DIR_FILES_CACHE . '/my-cake-' . $lessFileHash . '.css'; // cache file doesn't be, rebuild it if (!file_exists($cacheFile)) { $lessc = Loader::library('3rdparty/lessc.inc', 'my_block'); $lessc = new lessc(); $lessc->setVariables( array( 'backgroundColor' => $this->backgroundColor, 'bID' => $this->bID ) ); $lessc->compileFile($blockTemplateLessPath, $cacheFile); } // include generated css file $this->addHeaderItem('<link rel="stylesheet type="text/css" href="' . REL_DIR_FILES_CACHE . '/cover-picture-' . $lessFileHash . '.css' . '"/>'); }

If these instructions were a bit brusk, you tin can find a working case in ane of my github repositories, bank check this: https://github.com/Remo/concrete5-cover-picture/blob/chief/blocks/cover_picture/controller.php#L43-L81.

I hope this helps you to clean up your code!



vandusenthumbeth.blogspot.com

Source: https://www.codeblog.ch/

Related Posts

0 Response to "Invalid Form Token Please Reload This Form and Submit Again Https Concrete5"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel