How to Get Laravel Debugging to work with PHPStorm and MAMP Pro 5
This has been one of the more aggravating things I’ve had to deal with in setting up software for development. I’ve followed the official documentation from JetBrains, over 30 other blog tutorials, and literally failed in getting any of them to work.
I figured out an easy way to make the setup work so I’m sharing it in case someone else finds it useful and for self-reference since I’ll probably forget how to do this again in 6 months when I start a new project.
MAMP Configuration
- Load MAMP and setup your host. Make note of the host name as you will need it to configure PHPStorm.
- Go to PHP on the left under Languages.
- On the right under Extensions, check Xdebug (Debugger).
PHPStorm Configuration
- Load PHPStorm and load your Laravel project.
- Setup your PHP executable and interpreter as per the official documentation and then resume here.
- On the top right of PHPStorm, select Edit Configurations from the dropdown.
- Click on the Plus Button on the top left of the dialog and then select ‘PHP Web Page’.
- Enter a descriptive name in the textbox. I use the host name from MAMP so it’s easy to identify visually. Click on the 3 dots with next to Server.
- Enter a descriptive name. I use the host name here as well. For the host, omit the http/https and just add the host name from MAMP.
- Click OK
- Now add your breakpoints and click on the Debugger Button on the top right and PHPStorm will load the site into the browser and break when breakpoints are hit.
Happy debugging!
How to Automate Sending Emails through Outlook interop using C#
I was tasked with a tricky issue in sending emails. Due to security concerns, the client’s IT team was not willing to share SMTP information for their mail settings and was only willing to set up an account in Outlook directly on a dedicated machine without sharing the password with us to send the emails. The client’s ask was to send emails through Outlook without letting users see the emails or Outlook itself.
Installing Office Interop for Outlook
Sending emails through Outlook can be done using Microsoft.Office.Interop.Outlook but the documentation is really lacking. If you need to do the same, I hope this will save you the hours of time it took me to figure out what ends up not being complex code.
Create a new desktop application project in Visual Studio. Install the Microsoft Office Interop for Outlook. I used the NuGet package manager to install it since it wasn’t present on my system:
Install-Package Microsoft.Office.Interop.Outlook
Automating E-mails using C#
I created a static class to send the email through Outlook. Note that my error handling code was replaced with Debug.Writeline. Remember to modify it to handle errors or implement logging so it doesn’t fail silently.
Email.cs:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Outlook;
using Exception = System.Exception;
namespace Email.classes
{
public class Email
{
public static void SendWithEmbeddedImages(string to, string subject, string htmlMessage)
{
var missing = Type.Missing;
Application oOutlook = null;
NameSpace oNS = null;
Folder oCtFolder = null;
Items oCts = null;
MailItem msg = null;
var sHeaderPath = Path.Combine(Environment.CurrentDirectory, "emails", "header.jpg");
var sLogoPath = Path.Combine(Environment.CurrentDirectory, "emails", "logo.jpg");
try
{
// Create an Outlook application.
oOutlook = new Application();
// Get the namespace.
oNS = oOutlook.GetNamespace("MAPI");
//Assumes MAPI profile name is Outlook
oNS.Logon("Outlook", missing, false, true);
msg = (MailItem) oOutlook.CreateItem(OlItemType.olMailItem);
var attachHeader = msg.Attachments.Add(sHeaderPath, OlAttachmentType.olEmbeddeditem);
var attachLogo = msg.Attachments.Add(sLogoPath, OlAttachmentType.olEmbeddeditem);
attachLogo.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", "logo");
attachHeader.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E",
"header");
msg.Subject = subject;
msg.To = to;
msg.BodyFormat = OlBodyFormat.olFormatHTML;
msg.HTMLBody = htmlMessage;
//Show email
msg.Display();
//Send email
//((Outlook._MailItem)msg).Send();
oNS.Logoff();
}
catch (Exception ex)
{
Debug.WriteLine("Automate Outlook throws the error: {0}", ex.Message);
}
finally
{
// Manually clean up the explicit unmanaged Outlook COM resources by
// calling Marshal.FinalReleaseComObject on all accessor objects.
// See http://support.microsoft.com/kb/317109.
if (msg != null)
{
Marshal.FinalReleaseComObject(msg);
msg = null;
}
if (oCts != null)
{
Marshal.FinalReleaseComObject(oCts);
oCts = null;
}
if (oCtFolder != null)
{
Marshal.FinalReleaseComObject(oCtFolder);
oCtFolder = null;
}
if (oNS != null)
{
Marshal.FinalReleaseComObject(oNS);
oNS = null;
}
if (oOutlook != null)
{
Marshal.FinalReleaseComObject(oOutlook);
oOutlook = null;
}
}
}
}
}
Example on how to call the class:
var sEmailPath = Path.Combine(Environment.CurrentDirectory, "emails", "single.html");
var htmlMessage = "";
if (File.Exists(sEmailPath))
{
//Load HTML from file
htmlMessage = File.ReadAllText(sEmailPath);
}
Email.SendWithEmbeddedImages("toaddress@test.com", "Outlook Automation Test", htmlMessage);
email.html:
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
</head>
<body>
<table width="600" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td><img src="cid:header"></td>
</tr>
<tr>
<td>
Hello world!
</td>
</tr>
<tr>
<td><img src="cid:logo"></td>
</tr>
</table>
</body>
</html>
Important Notes and Gotchas
- CIDs need to be unique. I’ve seen them on all other posts with the format “file.extension@{random #}” but keeping it simple like in the code above worked for me with no issues with Outlook 2016. I did not test on older versions of Outlook to confirm as I no longer have access to them.
- Outlook ignores font rules in the HTML/CSS you code in the email and defaults to Times New Roman. I know Outlook uses the Word renderer but I have no idea why and the only solution I found was to update the default font in Microsoft Word. Yes, to change the font in Outlook, you’ll need to update the default font in Word. Here’s how to set it:
- Open Word
Go to Options -> Advanced -> Web Options
Change the default font in the Fonts tab
- Open Word
- Outlook only supports a subset of HTML so don’t forget to test and verify everything as most CSS formatting won’t work in Outlook.
How to Execute a Stored Procedure in Laravel 5.6
I’ve been stumped on this and tried everything I can think of but I can’t get Laravel to execute a working mysql query to reorder an ordering column when deleting a row.
Here’s a sample simplified query, which works directly in mysql:
SET @number = 3; UPDATE images SET order = (@number := @number + 1) WHERE id >2 AND project_id = 10
Laravel code that doesn’t update the database but throws no errors:
$sql = 'SET @number = 3; UPDATE images SET order = (@number := @number + 1) WHERE id >2 AND project_id = 10';
DB::raw($sql);
Other things I’ve tried which throw errors including saying there’s an error in the query:
DB::unprepared($sql);
DB::statement(DB::raw($sql);
DB::statement($sql);
DB::update($sql);
DB::select($sql);
I’ve also tried splitting it the statements with no luck:
DB::statement("SET @number = 3;");
$sql = 'UPDATE images SET order = (@number := @number + 1) WHERE id >2016 AND project_id = 10';
$update = DB::update($sql);
I tried a few other things which I didn’t log in Git but I had no luck getting any of it to work. I asked for help on the forums and people told me to use Laravel’s Eloquent model to update rows one by one which is pretty inefficient. You get extra trips over the network (especially important when the code is not on the same server as the database server since you can get dropped calls), extra connections to the server, the extra overhead of processing the query on the server and in the database, etc instead of just having mysql make the update.
The recommended solution may not seem like a big deal but I’ve run into issues where client connections have been dropped mid-update and left a table partially renumbered.
As a last resort and workaround, I opted to use a stored procedure to accomplish my goal. That presented its own can of worms as searching for examples on how to execute stored procedures in Laravel 5.x was also not easy. There’s nothing in the documentation and all the examples I found didn’t work.
Here’s what worked for me with Laravel 5.6, with mySQL 5.6.38:
DB::statement('call spRenumberComments(?, ?)', [$id, $projectid);
Self-signed SSL certificates not working with MAMP and Chrome
I use MAMP Pro for most of my PHP development and Chrome has annoyingly been blocking the self-signed SSL certificates MAMP generates, saying the certificate is not valid and “Your connection is not private”:
Thankfully, I found an easy solve to fix this. These steps assume you’ve created a host in MAMP. You’ll need to go to the SSL tab of the host you are trying to fix and
- Check the SSL button
- Click the self-signed certificate button.
- Fill in the fields in the dialog modal and click Generate
- You’ll be prompted to save the certificate. Choose whatever location you’d like.
- Click on the circle with the arrow to open the directory where the certificate was saved.
- In the finder window that opens, double click the .crt file (be sure it’s the same file name that’s in the SSL window in case you have multiple).
- In the Add Certificate window, click Add. I testing adding it to login and system and both worked, so add whichever you prefer.
- In the Certificates Window, double click the certificate. It’s easier to filter by name if you have a lot of items.
- In the next modal window, choose Always Trust from the dropdown.
- Close out the next confirmation window, and you’ll be prompted to authenticate with your mac login to save the updates.
Go back to Chrome, and reload the page and the certificate should work now:
How to get shape type in Visio using VBA?
I’m working with a Visio 2016 file with over 100 tabs and need to extract the data (mainly text, connector from/to, and shape) for data processing for a processing engine. I was trying to figure out how to get the shape type name in Visio using VBA. For example, in a flowchart, I’m trying to figure out how to tell if a shape is a process, decision, data, etc. The
visShape.Type
property seems to always return 3 which appears to be visTypeShape from https://docs.microsoft.com/en-us/office/vba/api/visio.visshapetypes. After hunting through all the available properties on the Shape object, I found that the shape.Master.Name property will return the shape name, but you need to check if it’s Nothing first in case it’s not a shape.
I didn’t do that and it kept breaking the script originally because some of the pages had text fields and the first few items on the first sheet I was working with were text boxes. Hopefully this snippet will save you the time I wasted figuring it out.
Public Sub GetShapeAndID()
Dim visShape As Shape
For Each visShape In ActivePage.Shapes
If Not visShape.Master Is Nothing Then
Debug.Print visShape.ID & " - " & visShape.Master.Name
End If
Next
End Sub
How to get website average latency in BASH
I was working on a project today and wanted to be able to get the average latency for an API that I was working on. Performance is a concern because we’re running the API over a VPN, and then SSH tunneling over to another server. I wanted a quick way to do it and wrote a little bash function that will calculate the average for me. I couldn’t find an example on how to do this online so I’m sharing in case anyone else runs into the same issue.
This is tested on Mac only. Add these two functions to your .bashrc and do a shellupdate in terminal to load the latest, or just grab my dotfiles from my github: https://github.com/gregvarghese/dotfiles
curlb(){
curl -s -o /dev/null -w '%{time_starttransfer}\n' "$@"
}
# Usage:
# latencyavg [# of times to run] [URL]
function latencyavg()
{
time=0.00
for (( c=1; c<=$1; c++ ))
do
num1=$(curlb $2 -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8,ja;q=0.6' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36' -H 'Connection: keep-alive' --compressed)
echo "$c - $num1"
time=$(echo "$time + $num1" | bc -l)
done
echo "Total Time $time"
echo $(echo $time / $1 | bc -l)
}
Usage example:
latencyavg 20 https://www.godaddy.com
How to fix npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
A friend was running into an error when using node to install a package. When installing the package he was getting the error “npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules”. The fix turned out to be pretty simple and he just needed to take ownership of the node_modules folder.
Open terminal and run this simple snippet to fix the problem:
sudo chown -R $(whoami) /usr/local/lib/node_modules/
How to remove wrapping tags in PHP Storm
How often do you code something and need to delete a wrapping link or div? I was using PHPStorm and had grabbed some code from another file that had links in the tags which weren’t needed in the new file. I didn’t want to manually remove each link and after a quick look around PHPStorm’s menus, discovered that PHPStorm has a really useful command to remove the wrapping element for you.
Select the element, then from the menu, choose Code > Unwrap/Remove… or use the keyboard shortcut, Command + Shift + Backspace and then choose the appropriate wrapping element to remove.
How to Prevent Raspberry Pi Zero from Blanking or Sleeping
I was setting up a Raspberry Pi Zero in an office to use for displaying a slide show of pictures on a TV in the waiting room and dismayed to learn it would constantly go to sleep after a few minutes. I researched and tried setting the consoleblank=0 in config.txt with no luck along many other solutions, but learned none of them worked for the Raspberry Pi Zero.
sudo apt-get update && sudo apt-get install xscreensaver
I’m not sure why, but I got an error that some dependencies were not installed. If that happens to you as well, run this command in terminal:
sudo apt-get --fix-missing
and then run the install for xscreensaver again
sudo apt-get install xscreensaver
Now under Preferences, you’ll see a new option for screen saver:
On the Display Modes tab, you’ll see a drop down for Mode. Choose “Disable Screen Saver”:
Your raspberry pi zero will now no longer go to sleep.
How to fix VMWare Fusion Pro 10 “Cannot find a valid peer process to connect to”
I recently got a new mac and was migrating a VMWare Windows Virtual Machine from my other computer. When starting the virtual machine, I received a random message from VMWare Fusion saying “Cannot find a valid peer process to connect to.”
The fix was rather simple as it was just Apple blocking VMWare from running. To fix it, follow these steps:
- Open System Preferences by searching in Spotlight or clicking the gear icon in the dock.
- On the top row there is an icon for Security and Privacy – Click that icon
- Near the bottom of the screen that appears the following statement
“System software from developer “VMWare, Inc.” was blocked from loading” - Click Allow