Friday, March 23, 2018

Word/Line deletion and navigation shortcuts in iTerm2 (Example)

Word/Line deletion and navigation shortcuts in iTerm2 (Example)



Word/Line deletion and navigation shortcuts in iTerm2

In OSX, ⌥+⌫ and ⌘+⌫ are the shortcuts for deleting a word and deleting a line respectively. ⌘+ ← and ⌘+ → are for going to the beginning and end of lines. By default, iTerm2 isn't configured this way, and there are a lot of misleading guides online. The following is what I've found to work on my machine.
  1. Open the preferences (⌘+,) and go to the Keys tab.
  2. Add a global shortcut key, and just type in your shortcut
  3. In the Action dropdown, select Send Hex Code
The hex codes for...
  • Deleting a word: 0x17.
  • Deleting a line: 0x15.
  • Moving to the beginning of the line: 0x01.
  • Moving to the end of the line: 0x05.
Just open a new tab, and it should work!
Here is a screenshot, for clarity.
Picture
EDIT: I've added code for beginning and end lines, and i'm currently working on turning this into a nice, complete list.

Sunday, March 18, 2018

How to integrate Recaptcha in Prestashop in 3 steps – More inspiration

How to integrate Recaptcha in Prestashop in 3 steps – More inspiration



Prestashop is one of the most used ecommerce on the internet BUT the contact form has no protection again the spam. Of course you can buy an additional plugin but I will explain how to integrate a spam protection without paying. You have to create and configure an account, change 2 sources. You can make it in 30 mn or less.
Here is a howto step by step for prestashop 1.6 (I don’t know about prestashop 1.7 but I imagine it should be similar).

1 Setup your Google reCAPTCHA if you don’t have it

Note the key and the secret key
You have to configure it and put your domain name.

2  Change the contact-form.tpl

First you have to change the contact form (client side) contact-form.tpl should be in your theme. Open an editor and search the submit botton
For me it is like that
<div class="submit">
 <button type="submit" name="submitMessage" id="submitMessage" class="button"><span>{l s='Send'}<i class="icon-chevron-right right"></i></span></button>
 </div>
 </form>

Just above add few lines of code. Replace key by your key
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="g-recaptcha" data-sitekey="key"></div>

That should look like that
<div>
 <script src='https://www.google.com/recaptcha/api.js'></script>
 <div class="g-recaptcha" data-sitekey="key"></div>
</div>

 <div class="submit">
 <button type="submit" name="submitMessage" id="submitMessage" class="button"><span>
{l s='Send'}
<i class="icon-chevron-right right"></i></span>
</button>
 </div>
 </form>

3 Change ContactControler.php

If you don’t have this source in override\controllers\front copy it from controllers\front
Then you have to add few lines to check if the captcha is ok or not
search the postProcess() function it should be at the begining (2nd function) and add
  if (Tools::isSubmit('submitMessage')) {
 $extension = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
 $file_attachment = Tools::fileAttachment('fileUpload');
 $message = Tools::getValue('message'); // Html entities is not usefull, iscleanHtml check there is no bad html tags.
 $id_order = (int)$this->getOrder();
 if (!($from = trim(Tools::getValue('from'))) || !Validate::isEmail($from)) {
 $this->errors[] = Tools::displayError('Invalid email address.');
// add the 2 lines from here
 } elseif (!($gcaptcha = (int)(Tools::getValue('g-recaptcha-response')))) {
 $this->errors[] = Tools::displayError('Captcha error');
// to here

Wednesday, March 14, 2018

Sticky Footer, Five Ways | CSS-Tricks

Sticky Footer, Five Ways | CSS-Tricks



A brief history, if you will.
The purpose of a sticky footer is that it "sticks" to the bottom of the browser window. But not always, if there is enough content on the page to push the footer lower, it still does that. But if the content on the page is short, a sticky footer will still hang to the bottom of the browser window.

#There is negative bottom margins on wrappers

There was a wrapping element that held everything except the footer. It had a negative margin equal to the height of the footer. That was the basis of this one.
<body>
  <div class="wrapper">

      content

    <div class="push"></div>
  </div>
  <footer class="footer"></footer>
</body>
html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  min-height: 100%;

  /* Equal to height of footer */
  /* But also accounting for potential margin-bottom of last child */
  margin-bottom: -50px;
}
.footer,
.push {
  height: 50px;
}
This one required an extra element inside the content area (the ".push"), to ensure that the negative margin didn't pull the footer up and cover any content. The push was also clever because it very likely didn't have any bottom margin of it's own. If it did, that would have to be factored into the negative margins, and having those two numbers not in sync doesn't look quite as nice.

#There is negative top margins on footers

This technique did not require a push element, but instead, required an extra wrapping element around the content in which to apply matching bottom padding to. Again to prevent negative margin from lifting the footer above any content.
<body>
  <div class="content">
    <div class="content-inside">
      content
    </div>
  </div>
  <footer class="footer"></footer>
</body>
html, body {
  height: 100%;
  margin: 0;
}
.content {
  min-height: 100%;
}
.content-inside {
  padding: 20px;
  padding-bottom: 50px;
}
.footer {
  height: 50px;
  margin-top: -50px;
}
Kind of a wash between this technique and the previous one, as they both require extra otherwise unnecessary HTML elements.

#There is calc() reduced height wrappers

One way to not need any extra elements is to adjust the wrappers height with calc(). Then there is not any overlapping going on, just two elements stacked on top of each other totaling 100% height.
<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>
.content {
  min-height: calc(100vh - 70px);
}
.footer {
  height: 50px;
}
Notice the 70px in the calc() vs. the 50px fixed height of the footer. That's making an assumption. An assumption that the last item in the content has a bottom margin of 20px. It's that bottom margin plus the height of the footer that need to be added together to subtract from the viewport height. And yeah, we're using viewport units here as another little trick to avoid having to set 100% body height before you can set 100% wrapper height.

#There is flexbox

The big problem with the above three techniques is that they require fixed height footers. Fixed heights are generally a bummer in web design. Content can change. Things are flexible. Fixed heights are usually red flag territory. Using flexbox for a sticky footer not only doesn't require any extra elements, but allows for a variable height footer.
<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>
html, body {
  height: 100%;
}
body {
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1 0 auto;
}
.footer {
  flex-shrink: 0;
}
You could even add a header above that or more stuff below. The trick with flexbox is either:
  • flex: 1 on the child you want to grow to fill the space (the content, in our case).
  • or, margin-top: auto to push the child away as far as it will go from the neighbor (or whichever direction margin is needed).
Remember we have a complete guide for all this flexbox stuff.

#There is grid

Grid layout is even newer (and less widely supported) than flexbox. We have a complete guide for it too. You can also fairly easily use it for a sticky footer.
<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>
html {
  height: 100%;
}
body {
  min-height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
}
.footer {
  grid-row-start: 2;
  grid-row-end: 3;
}
This demo should work in Chrome Canary or Firefox Developer Edition, and can probably be backported to the older version of grid layout for Edge:

Saturday, February 24, 2018

Raspberry PiからPushBulletにPushする - Qiita

Raspberry PiからPushBulletにPushする - Qiita



PushBulletのcreate-pushを参考に
push2bullet.sh
#!/bin/bash
AccessToken=[MyPushbulletAccessToken]
curl --header "Access-Token: ${AccessToken}" \
     --header 'Content-Type: application/json' \
     --data-binary "{\"body\": \"$2\" ,\"title\": \"$1\" ,\"type\":\"note\"}" \
     --request POST \
     https://api.pushbullet.com/v2/pushes
使用例
./push2bullet.sh Title MessageBody

Tuesday, February 13, 2018

Debugging Queries in Laravel ― Scotch

Debugging Queries in Laravel ― Scotch



Laravel provides a fantastic database query builder and ORM system named Eloquent. It makes running queries extremely simple and allows you to get records with minimal effort. However, there may be times when you need to build an advanced query and would like to see the actual SQL being generated.
In this tutorial let's go through some of the ways we can easily get access to this information. Starting with the simplest methods and moving into more powerful packages.
Before we jump in let's build an Eloquent query for a fictitious bug report that has been assigned to us:

Issue #22321
Problem: Searching users is showing to many results
Steps to reproduce: I search for "John Doe john@example.org" and I'm getting back hundreds of results. 
As we dig into the code, we find this query that seems to be where the problem lies:

$results = User::where(function($q) use ($request) {
    $q->orWhere('email', 'like', '%john@example.org%');
    $q->orWhere('first_name', 'like', '%John%');
    $q->orWhere('last_name', 'like', '%Doe%');
})->get();
Can you already spot the problem? If not, don't worry as we will start debugging this and see what is actually going on.

#Simple Query Debugging

The simplest method to see the query generated is by utilizing a ->toSql() method. All that we need to do is replace the closing ->get() with ->toSql(). Then printing out the results with the dd(), die and dump, helper.
Here is the updated query:

$results = User::where(function($q) use ($request) {
    $q->orWhere('email', 'like', '%john@example.org%');
    $q->orWhere('first_name', 'like', '%John%');
    $q->orWhere('last_name', 'like', '%Doe%');
})->toSql();
dd($results)
Running this in the browser will give us the following generated SQL:

select * from `users` where (`email` like ? or `first_name` like ? or `last_name` like ?)
This method is great for quickly seeing the SQL. However, it doesn't include the query bindings, only a ? for where they are to be inserted. Depending on the complexity of the bindings, this may be enough information for you to debug it.

#Listening For Query Events

The second option is to listen for query events on the DB object. To set this up above the query add this little helper:

\DB::listen(function($sql) {
    var_dump($sql);
});
Now when you load the page in the browser you will get the same output as in the simple query debugging section:

select * from `users` where (`email` like ? or `first_name` like ? or `last_name` like ?)
DB::listen is also more advanced, and it accepts two additional parameters to give us access to the passed in bindings and the time the query took to run:

\DB::listen(function($sql, $bindings, $time) {
    var_dump($sql);
    var_dump($bindings);
    var_dump($time);
});
Running this again will then display the following results:

string 'select * from `users` where (`email` like ? or `first_name` like ? or `last_name` like ?)' (length=89)
array (size=3)
  0 => string '%john@example.org%' (length=18)
  1 => string '%John%' (length=6)
  2 => string '%Doe%' (length=5)
float 35.63
As you can see, this gives us the query, the bindings, and the time the query took to run. With this, we can match up the bindings to the query.

#Debugbar Package

Another viable option is to install the Laravel Debugbar package. Once installed you will get a heads up overview of your app that is displayed at the bottom of the browser. It's a very full-featured package and will give you lots of insights into your application.
The part we want to focus is the query tab that outputs every query ran to generate the page.
debugbar-package
This gives us the full query with the bindings inserted into the correct place and a bonus of showing query hints to improve it.
Another advantage of having the query shown instantly like this is you can quickly spot areas that might not be eager loaded. This can lead to a significate database performance hit, and it's easy to notice as you will see the total number of queries being high.

#Conclusion

Have you spotted the error with the query now? Instead of using orWhere we needed to be using where. Here is the final code that fixes the bug:

$results = User::where(function($q) use ($request) {
    $q->where('email', 'like', '%john@example.org%');
    $q->where('first_name', 'like', '%John%');
    $q->where('last_name', 'like', '%Doe%');
})->get();
Which gives us the corrected query:

select * from `users` where (`email` like '%john@example.org%' and `first_name` like '%John%' and `last_name` like '%Doe%')
Now the next time you get stuck needing to debug a query you have three tools available in your toolbelt to get the job done. Happy debugging!
If you enjoy Laravel, join my weekly Laravel newsletter to stay up to date on all the latest Laravel news, tips, and resources.