Archives

Tag: PHP

  • Troubleshooting Problems Installing Craft CMS on Laravel Homestead


    Today I installed Craft CMS in for a new Praxis project. I use Laravel Homestead for my local development environment. It installs like pretty much every other PHP app on Homestead (use this guide by Matt Collins if you aren’t very familiar with Homestead), but I ran into a few annoying errors along the way:

    Mcrypt is required

    If Mcrypt is required shows when you first go to http://yoursite.local/admin to finish the install, it is probably because you are a good citizen and your Homestead box is actually up to date, running PHP 7.2 as the default. Here’s the issue: mcrypt was removed from PHP 7.2. Craft 2 still needs it. There are three solutions:

    • If you need PHP 7.2, you’ll have to install Craft 3. It is still under development as of this writing, so I didn’t take that path. (Update April 2, 2018 – Apparently Craft 3 is launching on April 4, so you won’t have this issue for long!)
    • You can install the mcrypt extension for PHP 7.2.
    • You can use a different PHP version. I took this route. Homestead makes this super simple by allowing multiple PHP versions. In your Homestead.yaml, set the php variable to php: "7.0" under your site in the Sites block. Here is what mine looks like:
    - map: craft-praxis.local      to: /home/vagrant/craft-praxis/public      php: "7.0"

    GROUP BY incompatible with sql_mode=only_full_group_by

    If you see this message, chances are that you are using MySQL 5.7.5+, which changed the way it deals with GROUP BY. See this StackOverflow post for the two solutions: Removing the ONLY_FULL_GROUP_BY option from sql_mode or adding the initSQLs database config settings in craft/config/db.php.

  • How to Back Up Your Laravel Homestead Databases


    Today I upgraded from Homestead 4.0.0 to 5.0.1 so I could test my sites in PHP 7. That was a major upgrade and a number of things changed, so I decided that I needed to back up my databases before I did the upgrade. I’d only ever dumped specific databases before, but TIL how to dump them all at once. Here is how to do that in Laravel Homestead:

    1. $ cd ~/Homestead
    2. $ vagrant ssh
    3. $ mysqldump -u homestead -psecret --all-databases > Code/homestead-YYYY-MM-DD-hh-mm.sql
    4. Test the sql file. I had a syntax error the first time and it only wrote out an error message. You’ve been warned.
    5. Move the SQL file somewhere safe. IE outside of any folder you might delete or change during the upgrade.
    6. After the upgrade, here is how to reload your databases in Homestead: $ mysql -u homestead -psecret < Code/homestead-YYYY-MM-DD-hh-mm.sql

    I had some major issues with the upgrade. When I first tried it, vagrant up hung at the SSH auth step and never moved. I went down a deep rabbit hole with my friend Eric Davis trying to debug the SSH issues, to no avail. My last trial was to roll back to Homestead 4.0.0, check my vagrant ssh-config settings, then try the upgrade with those settings. Then, miraculously, when I tried the upgrade again, vagrant up worked with no SSH problems! No difference in settings. I’m baffled, but relieved.

    FYI, there are some Homestead.yaml differences between Homestead 4 and 5, so make sure you have some time set aside to read the docs, update your yaml file, and rerun vagrant up --provision a bunch of times to get everything working again.

  • Loading scripts in WordPress with wp_enqueue_scripts


    Sometimes you need to put scripts on a specific page in WordPress. Frameworks like Genesis have boxes where you can add header or footer scripts. Most don’t, though. Here is how to load scripts on specific pages in WordPress with the wp_enqueue_scripts hook.

    In functions.php in your theme folder, you’ll need to add an action for the wp_enqueue_scripts hook. This will be a function pointing to the script.

    I’m using get_stylesheet_directory_uri() to link to the script. This means if your theme’s main style.css is in “example.com/wp_content/themes/twentysixteen/style.css”, your script should be in “example.com/wp_content/themes/twentysixteen/js/script.js”.

    Pick one the the scenerios below and add the code to your functions.php file in your theme. Make a backup of it first in case you mess something up.

    This will work for the whole site:

     function hello_script() { wp_register_script( 'hello-script', get_stylesheet_directory_uri() . '/js/hello-script.js' ); wp_enqueue_script( 'hello-script' ); } add_action( 'wp_enqueue_scripts', 'welcome_page_script' ); 

    This will work for just a specific page. Switch “052” with your page ID. Here is how you find the page ID.

     function about_page_script() { if ( is_page('052') ) { wp_register_script( 'about-script', get_stylesheet_directory_uri() . '/js/about-script.js' ); wp_enqueue_script( 'about-script' ); } } add_action( 'wp_enqueue_scripts', 'about_page_script' ); 

    If you have one of those fancy themes that generates a front page that you edit in the Customizer but it doesn’t have a page ID, but you only want it to display on the front page, don’t fret. WordPress has a is_front_page function:

     function front_page_script() { if ( is_front_page() ) { wp_register_script( 'front-page-script', get_stylesheet_directory_uri() . '/js/front-page-script.js' ); wp_enqueue_script( 'front-page-script' ); } } add_action( 'wp_enqueue_scripts', 'front_page_script' ); 
  • Hiding Categories from the Jekyll Paginator, Unless, and Insert statements


    Today I learned:

    Hiding Categories from Paginator

    According to the Jekyll docs, the jekyll-paginator plugin does not support categories or tags. That means there is no way to exclude a category as a whole. You can only exclude posts individually by including hidden: true in each post’s YAML front-matter.

    I’m hiding all of my TIL posts from the front page of my site, so I did a global find and replace to accomplish it.

    Mirror of If statement in Liquid

    Liquid has a neat concept that is the inverse of an If statement. It executes if a condition is not met.

    {% unless post.categories contains 'TIL' %} 	Code here to display all the things! {% endunless %}

    Inserting via mysqli()

    Using the mysqli() function I wrote about yesterday, here is how to insert something into a table:

     $connect = new mysqli($server, $db_username, $password, $db); $connect->query("INSERT INTO `table_name` (username) VALUES ('$user');");

    Make sure your variables are sanitized first! You don’t want someone doing a SQL injection.

    Eric Davis told me that mysqli() is the old way of doing things and I should check out PDO instead.

  • Connecting and Writing to MySQL with PHP


    Today I learned:

    Connecting to MySQL with PHP

     $server = "localhost"; $username = "username"; $password = "password"; $db = "dbname";  //connect $connect = new mysqli($server, $username, $password, $db);  //Check Connection if ($connect->connect_error) { 	die("The connection failed: " . $connect->connect_error); }

    Check if a table exists and create it if not

    This checks for a table called scorecard_test and creates it if it doesn’t exist. The SQL parameters for the columns are:

    • An integer called ID that is the primary key and auto increments
    • A username that can’t be NULL
    • A column called counter that has a default value of 1 if there is nothing passed, and the length can’t be longer than one digit
    • A column that holds the current timestamp.
     // SQL syntax $sql = "CREATE TABLE IF NOT EXISTS scorecard_test ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, username varchar(255) NOT NULL, counter int(1) NOT NULL DEFAULT 1, time TIMESTAMP )";  // Connecting, sending query, showing errors, and closing connection if ($connect->query($sql) === TRUE) { 	echo "Done!"; } else { 	echo "Error: " . $connect->error; }  $connect->close();
  • WordPress Plugins, Development Planning for New Developers


    Today I learned:

    Development planning for new developers

    Philosophies like Agile Development are great for teams working on large projects, but for someone just getting started with development and working on small projects, they can be a little much. For situations like this, Readme Driven Development strikes the right balance of planning out your project, writing documentation, and actually doing the work.

    Write your Readme first! (H/t to Eric Davis for telling me about this.)


    WordPress Plugin Basics

    I have a food & drink website where I post regularly. Lately I’ve been trying lots of kinds of coffee to dial in my ROK Espresso maker and I’m starting to reach the limits of how many I can accurately remember. I’ve been wanting to make a WordPress plugin for a while, so why not make a plugin that makes a Coffee Reviews custom post type? (The main goal here is to write my own plugin and learn how it is done, so please don’t suggest already made plugins that I could use.)

    I’m using WordPress’s Plugin Handbook to learn the basics.

    Barebones

    The most basic WordPress plugin is a PHP file with a plugin header comment. Here is mine:

     /* Plugin Name: Coffee Reviews */

    You’ll eventually want a lot more in the header. Here are the requirements.

    Hooks

    Hooks allow you to tap into WordPress without editing the core files. (Rule #1 is to never edit the core files.) You pass functions through hooks to extend or change WordPress functionality.

    The register_activation_hook() runs when you press “Activate” on a plugin. Since I’m making a custom post type, I’ll want to use the activation hook to refresh permalinks once the post type is created. If your plugin needs a custom database table, you can create that with a function passed to this hook.

    The register_deactivation_hook() is basically the reverse of the activation hook. When you deactivate the plugin, the items passed to this hook fire. I’ll want to clear the permalinks again.

    I made a barebones plugin tonight that registers the custom post type. I definitely have more work to do, but saving, hitting refresh, and seeing this appear never gets old!

    barebones plugin

  • Checking for Keys and Looking Up Values in Arrays, Restricting Files in .htaccess


    Today I learned:

    Checking for a key in an array

     key_exists($key, $array) 

    For the Toggl Slack slash command, I’m using it to check if someone’s Toggl API key is in the array in variables.php:

     if (key_exists($user_name, $toggl_api_key_mapping) == FALSE) { 	echo ":warning: You haven't set up your Toggl API key with this command yet. Get it at the bottom of https://toggl.com/app/profile and send it  to @$your_admin_name."; } 

    Notes:

    • Case sensitive. If you need it to be insensitive, use strtolower() on the $key
    • Boolean (returns TRUE or FALSE)

    Looking up a key and returning a value in an array

     $array['key'] 

    For the Toggl Slack slash command, I’m using it to set someone’s API key from the array in variables.php:

     $toggl_api_key = $toggl_api_key_mapping[$user_name]; 

    Blocking access to files via .htaccess

    If you are serving something on your webserver that you don’t want anyone else to be able to access, you can restrict access to by adding this snippet to your site’s .htaccess file:

     log.csv> 	order allow,deny 	deny from all  

    If you need only a certain IP address, you can achieve this by adding allow from 0.0.0.0 (replace that number with your IP address):

     log.csv> 	order allow,deny 	allow from 0.0.0.0 	deny from all  
  • Basic Logging with PHP and Syntax Highlighting in Jekyll


    Today I learned:

    Basic Logging to CSV in PHP

    I asked Eric Davis about logging for debugging and usage stats on my Toggl Slack slash command and he suggested that I look into writing to a CSV or JSON file. I opted for CSV.

    Here I build the array from the information I get back from Slack (plus a datetime stamp) and pass it to a file called log.csv via fputcsv().

     $log_array = array($date,$user_id,$user_name,$command,$text,$response_url,$channel_id,$channel_name,$token,$team_id,$team_domain); $output = fopen('log.csv', 'a'); fputcsv($output, $log_array); fclose($output);

    A note on fopen() – A lot of tutorials replace that 'a' with a 'w'. According to the docs, w writes at the beginning of the file, which is why my first couple tries overwrote each other. The a starts writing at the end of the file, which is always a new line since fputcsv() always ends with a line break.


    Syntax Highlighting

    I finally found a good solution for syntax highlighting in code blocks with Jekyll: Kramdown with Pygments plugin.

    Installation is simple: Clone the project to your _plugins folder and add it to the Plugins section of your _config.yaml, then you are ready to go.

    Usage is equally as simple: Specify the language at the end of the first line of your code blocks and the plugin will add the proper classes and highlight the code according to the language.

    Example:

    ~~~~ php echo "Hello world!"; ~~~~ 

    Will output:

    echo "Hello world!"; 
  • Unicode Conversions in PHP and Remote Git Repos


    Today I learned:

    Converting Unicode quotation marks in PHP

    Unicode quotation marks (sometimes called smart quotes) are those curved/slanted single and double quotation marks: “ ” ‘ ’. The ASCII ones look like this: " '. They are usually interchangeable in word processing, but the stylized ones sometimes cause issues on the web (in a parser, for example).

    To convert one to the other in PHP, use iconv():

     $output = iconv('UTF-8', 'ASCII//TRANSLIT', $input);

    If you use OS X and want to turn off smart quotes, go to System Preferences > Keyboard > Text and uncheck “Use smart quotes and dashes.”


    Remote git repositories

    Using git locally is one thing, but it is far more powerful (and exciting!) to push that code to a remote repository like Github for display and collaboration.

    Assuming you have a local repository that wasn’t cloned from a remote one, you’ll need to hook it up to a remote repository:

    $ git remote add origin 

    If there is code already on the remote repository, you’ll need to merge it in to your local:

    $ git pull $ git merge origin/master

    Then push your committed files to the remote repository:

    $ git push origin master

    For a great beginner’s guide to git, check out Roger Dudler’s git – the simple guide.


    Toggl Slash Command for Slack

    Today I released my first personal project on Github: Toggl Slash Command for Slack.

    It is a custom slash command that enables users to put time entries into Toggl from Slack.

    If you use it, I’d love to know! It is in its rough early stages, but I have some future additions planned for it, so stay tuned.

  • CSS Inheritance, Datetime Conversions in PHP


    Today I learned:

    CSS Inheritance

    • In CSS some styles are automatically inherited from their ancestors (i.e. elements which contain that element). For example, if you set body {color: red;}, all text inside the body element, regardless of what other elements the text is in, will be red unless the color style is set on one of those other elements later in the .css file.
    • This simultaneously makes writing CSS a breeze and debugging it a bit of a headache. There isn’t a great way to tell if a style is inheritable without looking at the docs.
    • If you encounter an issue where your style isn’t displaying as it should and it is not responding to changes, check the docs to see if the style can be automatically inherited. If so, check the ancestors of the element you are working on.

    The issue I ran into today was that my

     snippets kept wrapping no matter what overflow and width were set to. It turns out that word-wrap is automatically inherited and I had it set on an ancestor element.


    Date/time conversions in PHP

    Date conversions are tricky. Thankfully, PHP has some built-in functions to make this easier.

    Example: date("c", time()) will take the current time (provided as a Unix timestamp) and convert it to ISO 8601 format.

    Unix timestamps are the number of seconds that have elapsed since the Unix Epoch (00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970). They can be frustrating at first because they are so foreign looking, but they are really useful because:

    1. They are not subject to timezones.
    2. Since they are simply seconds, time math with Unix timestamps is pretty simple: Convert the time you wand to add or subtract into seconds and do the direct calculation. Then if you want to get it back into a recognizable format, use one of the functions above.

    I’ve been working on a custom Slack command to input time into Toggl, so I’ve been doing quite a bit with time conversions to get everything right.

  • Photoshop Patterns, Homestead Provisioning, Composer Basics


    Today I learned:

    Tiling Photoshop Patterns

    I’ve been making some patterns for the header images on these TIL posts in my down time the past few days. There are two ways to tile patterns in Photoshop. One is manual and time consuming, the other is fast, easy, and less prone to error.

    • The manual, time consuming way is to open a pattern in one layer, duplicate the layer multiple times, and move the layers so that they line up in a tiling pattern. While PS is pretty great at snapping items to a grid, sometimes they don’t always line up and you only find out after you export the image.
    • The fast and easy way is to open the pattern in PS, go to Edit > Define Pattern…, then use the Pattern Stamp Tool to paint the pattern you just created across a large canvas.

    This would have saved me a lot of time on the first nine headers, but c’est la vie. This will definitely save me time going forward.


    Homestead Provisioning

    I use Laravel Homestead for my local PHP environment. Provisioning a new site is something I’ve done multiple times, but I do it so infrequently that I have to look it up each time. So here are my quick notes:

    • Create the site folder in ~/Projects/
    • Map the folder and domain in ~/.homestead/Homestead.yaml
    • Map the domain to 192.168.10.10 in /etc/hosts/ (reminder: $ sudo nano /etc/hosts/)
    • Run $ cd ~/Homestead
    • Run $ vagrant up --provision or $ vagrant reload --provision if vagrant is already running.
    • Site should now be accessible locally.

    If you need a new database for this site and load it from a SQL dump:

    $ vagrant ssh $ mysql -u homestead -p -e 'create database DBNAME;' $ mysql -u homestead -p  DBNAME < path/to/file.sql

    Composer Basics

    Composer is a dependency manager for PHP. I’ve used Composer, but like Homestead provisioning above, I’m a little rusty. Writing it down helps me remember.

    After you’ve installed it (I have it installed globally), the basic usage is:

    • Set up composer.json in the directory you are working on. A basic structure looks something like this:
    {     "require": {         "ajt/guzzle-toggl": "^0.10.0",         "corneltek/getoptionkit": "~2"     } }
    • In that directory, run $ composer install to install the dependencies listed in composer.json. They will be in a file called vendor.