I Provide the technical cover for the worlds finest cookery school. I find ways of solving our problems and this blog shares them with the world.
Don't wanna be here? Send us removal request.
Text
Restructoring Where to run Laravel Scheduler from.
In Laravel there is a great scheduler built in.
You need to run a OS based job that calls a console action every minute
This works great, and various functions allow you to run your scheduled actions at pretty much any interval you want.
I currently use scheduler to
Check for bookings every minute during the day
Check for bookings every 10 minutes at night.
Clear up cache directories once a day
Prune models every day.
Send out student emails at a specific time daily.
However I find that putting information into the schedule method of the console Kernal to be not the best place to put this info. For one thing when searching I type 'schedule' but that wont find my file so it seems like the wrong place.
instead what I do is create a Scheduler class and place it in the Consol directory with a single method
public function schedule (Schedule $schedule)
inside this I can reference the $schedule object and call all my schedules
public static function run(Schedule $schedule) { >User::LoginSystemUser(); Self::CheckInternetBookings($schedule); $schedule->call(new RemoveSpacesFromNames)->name('Remove Space from front of names')->everyThirtyMinutes(); $schedule->call(new UpdateNullAccommodation)->name('Update Accommodation 1900 to null') ->everyThirtyMinutes(); .... }
and I just need to this in the kernel
protected function schedule(Schedule $schedule) { Scheduler::run($schedule); }
I find that this is a much better layout. Hope this is helpful
0 notes
Text
Facades or Helpers?
In Laravel code we often use helpers and facades interchangably and many of the facades that are used most in Laravel are also available as Facades
eg.
view('order.show'); view::make('order.show');
This is so prevalent, that I thought that helpers were part of Facades so when I went to create my own facade I couldnt understand why the helper function didnt work.
Slowly it dawned on me this was not the case and what I really needed was a facade and a helper function.
I found this very helpful article on Laravel news
https://laravel-news.com/creating-helpers
This explains very simply what helper functions are, where and how your crate them and how you autoload them.
Now I have a facade and a helper function and I'm happy.
0 notes
Text
Further integration with Laravel
A few weeks ago I wrote a short blog post outlining some of the early success and challenges I had had integrating Laravel with a large legacy application. It is not possible to start again from scratch, so I am using Laravel to provide the application development process with a modern platform while continuing to allow the legacy code to run unhindered.
Since then i have continued to integrate the code and have come upon and successfully solved several integration issues.
Laravel must be loaded in a function.
Laravel Takes over all Error Processing
Sometimes you think Laravel is causing a bug but its not.
Sometimes you can use both
Integration
At the begining I was unsure exactly how integrated I would make the Laravel Code and the Legacy Non Laravel Code. I began by only loading the Laravel Codebase when I needed it, but quickly realise that having laravel functions available provided a huge advantage to the legacy codebase, so now I just load laravel in the config load file for the legacy codebase, ensuring I have access to all functions at all times.
Together but seperate.
One obvious area for seperation is in views. My legacy code base uses smarty, which I have always liked, and have been using since V1. If laravel had an option to use Smarty I would have continued with it, but thats not possible, so I use Blade with my new Laravel code.
This was a simple decision. Old code would continue to use Smarty, new code would use Blade.
Then...
Then I decided to provide information about a new feature (Subscriptions) to an old feature (Booking) so I pulled in the new Subscription Eloquent model into my view_booking page and passed it to a new Smarty template to use as a partial in the main Smarty Template? But why write a new template in Smarty, if I'm slowly going to be moving to Blade? So instead I called
$SubscriptionsHTML = View::make('bcs.booking.tab_subscriptions',['Subscriptions' => $Subscriptions]);
This runs my new Blade Partial through the blade engine and returns my HTML which I can pass to Smarty as part of its content.
This may seem like I'm mixing up lots of things and heading for making myself very confused, however I see it differntly. i have decided to embrace (Laravel)[https://laravel.com/] and use it moving forward. The more I integrate it with the old codebase the more I will be willing to write ALL new code in any part of the codebase using the Laravel Framework.
I have been amazed at how well I have been able to integrate an existing project with Laravel.
0 notes
Text
(Attempting to ) Integrating Laravel into a Legacy Codebase
We have a reasonably large codebase for a PHP application that provides the main business functions here at the cookery school. It was written orginally in 2004 when I thankfully decided to see what would happen if I turned our main business app into a web app written in PHP (rather than clasic ASP) instead of another Delphi desktop app which was what I was planning.
The usability and speed that I got up and running using PHP 4 was wonderful but it is very legacy.
Very very few objects
All functions to capture logic
Each page has its own php page.
All pages pull in all code (pretty much).
Very little file structure, all files in a two directories. pages and includes
No Namespaces
Recently I have been learning an ready about Laravel. This has been on everyone else’s radar for a long time and came on mine about 4 years ago when I was introduced to Lumen by a colleague. Having spent lockdown going through the excellent Laracasts introduction to Laravel 7 I felt like it was time to use Laravel a bit more.
Sure I can use it for any new api’s or apps, but what about leaveraging some of the benefits for our main application. Well its worth a try.
This blog post (possibly posts) tells my story of how I got (or did not get) a legacy codebase working in tandam with Laravel and modern PHP 7.
Working in Parallel
First things first: get a Laravel App and my primary core application both running on the same domain. As I have mentioned before I use the wonderful CaddyServer to host our sites. I set up a new site and pointed it to a directory on my server.
I created a new Laravel app in the directory and pointed caddy to its ‘public’ directory
Laravel
\App \Public \resources
Next I cloned my entire core application into the public directory (making sure not to overwrite the index.php file here).
How to get it working?
Just like this, Laravel works no problem, you can set a route and as long as the route directory doesnt really exist in my main application, I can get access to a controller and view a new laravel app. I can also access my legacy application on a standard url since the files all exist in the public directory.
However I dont want to rewrite my entire application straight away, so I do want to be able to call functions in my legacy application from Laravel.
First off I tried simply calling the function from the controller.php after include the appropriate files. This inevitably led to an error that the function was not found. This of course was due to there being no namespaces in my legacy code.
The Reason for Namespaces
I immediately got an error saying that
Logger can not be redeclared
My code declared a logger function which unfortunately is pretty common and laravel declares a logger also. Without namespaces I was stuck since PHP didn’t know which logger I wanted. I had come upon the fundamental reason for declaring namespaces in the first place.
So I added a namespace at the beginning of the file that contained my function.
Namespace BCS
Then I got a different error. Now I need to use Namespaces everywhere.
My code calls PDO but does not call \PDO
So I change the few instances where I find
PDO::FETCH_ASSOC
to
\PDO::FETCH_ASSOC
Then next I get error for functions that my legacy function calls. So I add namespace BCS to those files also.
and it all starts working (for that one function).
Ok. So far so good.
Next I got back and try to view my legacy application.
Its all broken!
By putting a few namespace BCS in my legacy code, I had broken the app. Namespaces seem to be an all or nothing. My entire legacy app needed to be in a namespace or none of it.
With a quick find and replace on the two primary folders in my application, I inserted the line
namespace BCS
at the begining of each and ever file and although there are still a few errors, which I am workgin through, I now have my legacy app up and running again on the BCS namespace and I can call functions if required from my new Laravel app.
I’ll see if I do finally hit a wall I can’t get past or if I can slowly convert my old legacy app into a laravel app, one page at a time.
Next up - Calling Laravel Controllers from my Legacy App!!
Using Laravel Classes in the Legacy Application.
Now that I have the two applications working seperately withing the same file structure and my new Laravel code can call functions in my Legacy application I had a lot of what I need.
This will allow me to create new section of the application and create them in Laravel, calling into the old legacy app when required to provide some logic I do not with to duplicate.
What about the modifications to the legacy appliation though?
I am hoping that using laravel will give me access to all the great features and conventions that Laravel provides. This I can do with new code, but what if I want to add code to an existing feature that cant easily be moved out into the new section?
Calling Laravel Objects from Legacy Code
Wouldnt it be cool if I could declare a Eloquent Class in Laravel and then create an instance of that class in my Legacy Application? That way I could really share code.
Starting Laravel
The entire Laravel Application is run from a single file public/index.php, which despite a lot of comments is only actually about 5 lines of code
define('LARAVEL_START’, microtime(true));
require __DIR__.’/../vendor/autoload.php’;
$app = require_once __DIR__.’/../bootstrap/app.php’;
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle( $request = Illuminate\Http\Request::capture() );
$response->send();
$kernel->terminate($request, $response);
I tried simply including this file. It should load Laravel and allow me to create a new instance of my object right? Well yes, but it just routes to the home page of laravel, which isnt useful.
I took a look at the code in index.php and decided that I probably needed it all except for the last two lines.
$response->send();
$kernel->terminate($request, $response);
I created a new file called loadlaravel.php and put the contents of index.php into it but commented out the last two lines.
BINGO - It Works.
So now I have a new laravel app that can call functions on my legacy application, and a legacy application that can use laravel classes.
Now to write the code and see where I go.
0 notes
Text
Very few things are truly boolean
When writing code and particuarily business applications, there are certain things that are true or false, or seem to have only 2 possible values
Examples
Does a customer want
Accommodation
No Accommodation
Leaving aside any discussion of non-binary assignment of gender these two options leave out a very important third option.
The customer has not chosen ?
Anytime you are choosing a boolean value for something in code or in the database, think. Can this value really be only true or false? Are we sure there is a not a 'Has not choosen'? value?
If so don't make the field boolean, make it something else.
0 notes
Text
€1000 a year for Open Source
Ballymaloe Cookery School like EVERY SINGLE BUSINESS on the planet relies on a huge amount of open source software to run. We use Caddy Web Server to run our internal line of business websites all served over https with LetsEncrypt TLS Certs. Our main customer facing site runs on Drupal and mariadb.
That is not to mention that most of the routers on our network run some form of linux.
The world today only runs because of Open Source Software, and businesses such as ours can only do what we do because of open source software.
Giving Back
Ballymaloe Cookery School is pledging to give a minimum of €1000 a year to support open source projects. I will update this post as we decide which projects to support. This is something we encourage all businesses large and small to do.
If you are hesitant to spend this money just imagine what it might cost if you had to run your website on a proprietary server or buy a licence for your database or create your own CMS from scratch.
0 notes
Text
Simplifying Code Review with Github and Caddy
I've been involved in the Caddy webserver project for a while now and use it as the main webserver for all our internal admin applications.
It is super simple to use, very easy to configure, a breath of fresh air after years of wrestling with apache, ohh and it (makes setting up a https site)[https://caddyserver.com/docs/automatic-https] so (trivial)[https://caddyserver.com/docs/automatic-https] you forget that was even a thing.
It comes with lots of great modules for doing lots of cool stuff such as browsing folders, using markdown, automagic https, fastcgi, proxy etc, but also has a whole host of 3rd party plugins that can be build right into the executable via the build server at caddyserver.com. One of those is a really great plugin called git by Abiola. This plugin will pull your repo from a github (or other) repository and respond to any commit git hooks, to make sure your site is kept up to date with any changes.
I had ignored it for a long time thinking it wouldnt work with private repos on github, but now that Windows git / github integration is better and https rather than ssh is the standard way to push changes to github on windows, it all seems to work brilliantly.
We are only a two man team and recently we started using github private repos to code review pull requests. This is fine for the codereview part but its always a bit of a pain to test out the changes on the branch prior to merging.
This is where caddy and git plugin come along.
update your caddy file with the new branch and restart.
githubbranch.example.com { root c:\\www\\mysite\\gitbranch git { repo https://github.com/tobya/privaterepo hook /webhooks/xxcaddygithook secretpassword branch issue27 } }
Now this will pull down the new branch and we can try it out there and then.
0 notes
Text
Open Whatsapp via url
We send out an email after someone has been on a cookery course with us asking for feedback. We also ask them if they would like to send us a photo via email, text or whatsapp so we can recognise them when they come back.
I wanted to make the suggestion to send us a whatsapp a link so as to make it as easy as possible for someone to send me a photo straight from the email. I found lots of examples about how to open whatsapp from a link and lookup an id, but I wanted them to send it direct to my phone and my number is probably not in their phone. This simple snippet does it.
whatsapp://send?text=Here+is+my+photo&phone=353871111111
use this as the href in an anchor tag and it will open whatsapp with the text, ready to send to my number.
0 notes
Text
Keep cURL secure.
Recently I had a familiar error in a php script I was writing using the Dropbox api.
cURL error 60: SSL certificate problem: unable to get local issuer certificate
I've seen this error or similar before and I sighed. Basically this means that while my code is trying to connect to a https secured site, it is unable to verify that the Certificat Authority (CA) that issued the cert is valid, this is all about the trust for certs.
If you search for this issue online you will find many many results on Stackoverflow.com and other sites telling you to simply put -k or (more succinctly!) --insecure for your curl options to tell curl to simply assume that the cert if valid. For those of us (myself included) who don't really understand encryption, the idea of our communications still being encrypted but not verified, seems to be harmless, its the encryption we want, so what's the harm.
Its really not!
The more --insecure parameters out there peppering scripts the easier it is for someone to impersonate dropbox.com and have great fun with all my and your files.
The Solution
Before abandoning all hope, I thought I'd do a search for a solution and found a really simple one courtisy of a Sven0188 on Laracasts.
https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate/replies/37017
The solution is to download the CA list from the curl website. Download the file and save it somewhere useful, then tell php about it by modifying this line in your php.ini file
[curl] ; A default value for the CURLOPT_CAINFO option. This is required to be an ; absolute path. curl.cainfo = C:\PATH\TO\YOUR\cacert.pem
restart your webserver or php process, and VIOLA your problem is solved and your secure.
everythinghttps
0 notes
Link
0 notes
Text
Why is your client not open source?
Are you a software company that charges for a server product?
Do you have a free client that customers use to connect to your product?
Is it opensource?
I bet the answers are
Yes
Yes
No
If your main product is a server product that people pay for and you have invested time and money in a client that people use to connect to it, why is it not open source? You have nothing to lose.
I’m specifically talking about companies such as
Perforce: An excellent pay for SCM system that is used by a huge number of companies to manage their codebase and file assets. They have an excellent client P4V which does most of what you want to connect. They have an API that the client and any other client uses. It is not open source.
Microsoft SQL Server: Microsoft's Database Engine. The main microsoft client SQL Server Management Studio is not open source.
Neither of these companies sell their clients and infact have free versions of their server products also, however neither is willing to open source their client.
If they open source their clients they would enable several things.
An interesting example of how other customers can use their API.
If you have an API that allows programmers to connect to your product, presumably you want as many customers and third parties to build against it, after all that’s the whole point of having an API, is for people to use it. Also you want there to be lots of examples of how to use your API on your website. Now if you opensource the client that you have taken such care in creating you give all your customers a great starting point to build their own product that uses your server, and see how it is done.
It also provides the best kind of documenation and examples, a working product.
It will build customer loyalty
Now instead of complaining about how your client and creating annoyance everytime they use it, your customers now have the option of improving it. They are the people who use it the most and often they are programmers (as in the case with the 2 products above). These people will improve your product to make it work better for them everyday.
Your product will improve.
With an open source client, you now have the potential for people to make changes to your client and all those changes can be fed back to make your product better, thereby making your server product better than the competition.
If you work for a company that has a server product - open source your client.
0 notes
Link
0 notes
Link
i have recently gotten involved in the #caddyserver project on github.com which is a little webserver written in GO which provides https out of the box, by connecting to letsencrypt and requesting a TLS Cert for any site you try to run. The simplest, fastest, most incredible way to do https you'll ever find.
0 notes
Text
Github now offers unlimited Private Repos
Following up on my last post, https://Github.com now offers unlimited private repos for a private account which is brilliant as that was a major stumbling block for a lot of people in trying to decide what to upload to github.
0 notes
Link
Upgrade your Github Account
Github is amazing. If you are lucky enough to be in a position where you can afford $86 a year for one of the most enabling technology websites to find its way onto the internet, then I implore you to upgrade your github account to a paid one, whether you need private repositories or not. Github as a company needs to survive, and if you use its services and you can afford a beer each week, then you can afford a github subscription.
Sign up now
0 notes
Text
Adding a Custom Github Repository as a dependency in Composer.json
Adding a Custom Github Repository as a dependency in Composer.json
I am a bit slow to the game, but I have just discoverd composer. For those of you who don't know its like npm for php. If you are still not with me, its a utility that allows you to take the hassle out of downloading all those pesky libraries you need for your app to work. You specify once in a composer.json file in your root directory what libraries you want installed. Then you call
composer install
on the root directory and it downloads them all from github etc into your vendor directory . However that is all fine and dandy if the author of the package has added a composer.json file to their repo on github.com and added it to the packagist website, which is often the case for php libraries, but not for javascript ones.
I though there has to be a way to specify a specific .git repo on github that I want to download. Its very difficult to find this information on the composer website. But with the help of this Stackoverflow.com question, I discovered how to add slickgrid to my composer.json file.
{ "repositories": { "slickgrid": { "type": "package", "package": { "name": "mleibman/slickgrid", "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/mleibman/SlickGrid.git", "reference": "master" } } } } , "require": { "mleibman/slickgrid": "2.1.0" } }
Firstly you need to add a repositories item to your file, with a complicated set of attributes to define where you are getting the code from, then in you standard require section you reference the package you have defined, and Voila composer will fetch it.
0 notes
Text
unprint_r
I recently found myself in a bit of a pickle. I had deleted a data file that I had been working on while creating a web utility. It wasnt the end of the world, but it would be a good hours work putting all the data back in and i didnt really want to do that.
I did however have a debug dump in a file that I had obtained by doing a
print_r($data);
in my code. This is regular, but is generally a one way process, there isnt a built in unprint_r in php. However stackoverflow.com and its many brilliant users to the rescue.
I found this question
http://stackoverflow.com/questions/7025909/how-create-an-array-from-the-output-of-an-array-printed-with-print-r/28687593#28687593
and this answer
http://stackoverflow.com/a/28687593/6244
The code got me completely sorted very quickly, and I put it all together onto github
https://github.com/tobya/pprint_R
0 notes