CakeDC Blog

TIPS, INSIGHTS AND THE LATEST FROM THE EXPERTS BEHIND CAKEPHP

Modifying Requests Like A Chef

Since the version 2.x of CakePHP has a requests and response objects, they are provided an abstraction around HTTP Requests and responses. If you are not familiar with CakePHP, it’s a common step when you bake and use $this->request->data instead of $_POST. Most of the time, we need to modify and append values on our Request data. This can be an identifier of logged user or values for any fields. In many situations, implementations will like this: Data can be modified easily - you just need to call withData or withParsedBody method and after set the Request  (you can also modify the query calling withQueryParams): Both implementations will generate the same value, but if you have a keen eye, you will see that the second implementation is more clear. Also, our Request has these values on data. This information can be useful when you use Components from Plugins, as they will expect the values on Requests.   That’s all bakers! I hope this content is useful for you and will improve your requests!  

Where you SHOULD be marketing your bus...

Marketing is an essential part of your business’ success. I don’t just say this because I myself am a marketing connoisseur... or maybe I do. But either way, I’m going to shoot you some quick knowledge about getting your name out there... specifically into the cyber world.   

Social media 

Branding is very important here. This will be another blog for another time... but having a uniform look, format, font, etc will help you look professional and stand out. Some of the platforms I work with for our company is Facebook, Instagram, Twitter. In our industry, Twitter is our cake and frosting (see what I did there). Most developers have a Twitter and use this to interact with other developers, frameworks, and companies. Having a company page allows you to engage with your followers, have conversations, and build relationships. Remember, you need to be posting things that are important for those who follow you to see, and when they reach out, be ready to respond.  For business contacts and networking, I am a big fan of LinkedIn. This platform is an easy way to connect and search for others in your field. Also, it's a good way to find people looking for your specific services. Very business. Very professional.  You definitely need to get to know your audience. Tracking your social analytics will tell you where you stand out most. Then, you utilize that information!  

Ads

 I’m a fan of Google Ads. While I know that the idea of paid advertising isn’t ideal or financially possible for everyone, there are other options. Keeping up with your SEO, or search engine optimization, will help with organic ads. Organic ads is a fancy way of saying free clicks, or free adveritsing. When people are searching Google for services or phrases pertaining to your business, then your site will show in the results. Obviously if you pay for ads, you can manually add phrases and terms that may be searched for... and these are called keywords. I think Google Ads pointers may be a good blog for me to share in the future *makes mental note*.    Speaking of Google, make sure your “my Google business” account is up to date, otherwise you will literally NEVER show up on the search engine. Even when someone specifically searches for you or your company.   

Email Marketing

We must be careful here. Gone are the days of spam emailing... and cold calling? Please don’t. I’d say most people are ready to get restraining orders against telemarketers. Just me?  However, if you have specific things (sales, offers, important news) to share with your customer base, then by all means - onward. At least emails can be ignored if they are unwanted. If you want your email to be opened, make sure that you are offering your recipients something worth clicking (specials. Giveaways. Etc.). A good platform to help you with this is MailChimp, but there are soo many ways to generate these emails, and many even offer pre-made templates... so no excuses.   

Newsletters

Similar to email marketing, there are newsletters. The difference here is that the people who will be receiving your monthly (most likely) newsletter are only those that have chosen to. “Subscribers” sign up to receive these emails. Usually, these aren’t offers of sales, but rather news, events, tips etc. You can get an idea of what I mean by checking out the CakePHP Newsletter archives. 
  So let's close with some quick facts: Newspaper advertising? Out Telemarketing? Out  Print? Maybe  Billboards? If the price is right and you are local to certain areas. International companies, like CakeDC do not benefit from this type of print, unless we could put one in every city around the world. I think that would blow my marketing budget pretty quick.  If you are a freelancer, I definitely suggest Fiverr. Let people find you. Essentially you get quality leads for free.    All of these marketing platforms and items need to be explained in deeper detail, so if you have any questions feel free to reach out to me!  

Benefits Of Upgrading

Let’s talk more about upgrading your CakePHP application. In last week’s blog, we talked about why you should hire externally for all of your upgrade needs. You may have been thinking… but why would I (or my company) even need to spend the time, effort, and money on upgrading our projects. Well… for many reasons. You need better security, compatibility, functionality.  You’ve seen our posts, you know what needs to be done. Your old CakePHP application needs to be updated.  I want to remind you about some of the benefits that there is to upgrading.   

SECURITY

The more maintained a CakePHP version is, the more security it can provide. This not only protects the projects themselves, but can also give you peace of mind knowing that the latest versions will be functional a lot longer than say CakePHP 2.x. And of course, the latest releases fix a number of security issues. No company wants to offer quality services to their customers,  and end up with a security breach that was out of their control. It is extremely important to get ahead of the security issues on the front end. Be proactive, and you won’t have to be reactive.  The biggest concern is that many hosting providers are abolishing old PHP branches, essentially overnight. This is why it is important to be aware of when to migrate/upgrade and do it before it is too late. You can see a list of the end of life date for each unsupported branch of PHP HERE.   

PERFORMANCE

CakePHP 4 follows the latest conventions, helping your application run faster and smoother. Old sites / applications run slow… that is no secret. I promise you one thing, today’s Google searcher will not think twice to do a different search if the site is lagging (ain’t nobody got time for that).  Also, migrating to a current PHP release over 5.6 and using the new ORM, could lead to improvements over 50%. So I mean, win-win.    If you are wondering about your performance, speed, or  which versions of PHP you are running on, you can use tools like Pingdom - https://tools.pingdom.com/ or Google Chrome Devtools - https://developers.google.com/web/tools/chrome-devtools.  

SCALABILITY & TOOLS

CakePHP 4 is shipped with best practices to streamline horizontal scaling and deployment into containers. As new tools and plugins are released, they may only be compatible with the latest versions. Currently, there are over 900 updated plugins, see here: https://plugins.cakephp.org/, covering from background job processing, image processing, CMS, file upload and management, cache, and more. This provides more features and results in developers WANTING to use and work with the framework. 

Of course there is a long list of additional benefits, but these are some of the most important. 2021 seems to be turning into the year of upgrades. Don’t get left behind!

Why You Should NOT Upgrade Your CakePH...

There are many reasons that CakePHP recommends upgrading. But should you, really? Contrary to what you would expect, I am here to tell you that maybe you should not upgrade your application. WHAAAAAAT? I said what I said. The answer is no… but yes, the application should be upgraded. What do I mean? I mean that SOMEONE should upgrade to CakePHP 4, but that someone should not necessarily be you or your team.  Let’s be real… upgrading takes time. It will take priority and focus. Is extra time something your team has? Usually not. This is why I suggest outsourcing for any upgrading.   

Prioritization

Perhaps your team is extremely busy with internal work, and you just can't fathom the idea of utilizing your resources on a time consuming project, such as upgrading. I would imagine that it’s not an easy task to go to your CEO / IT manager and explain why you were unable to meet a deadline due to unexpected complications during a migration. This is one reason that it would be beneficial to hire a team. Then, you are able to keep your team working on tasks that actually add value to your business, providing the best service for your customers…. What I am trying to say is let us doing the boring tasks of upgrading    

No Training / New Skills

Even if a junior level developer was tasked with upgrading one or all of the company's projects, why pay for their time when it is not advancing them in any way? During an upgrade, the tedious work is not resulting in any new skills for the developer. There is no training, or development skills to be learned during an upgrade process. This is a huge factor for a lot of CakeDC’s upgrade clients. The money and time spent for doing these actions internally does not provide long term gains. For us - we need to know the ins and outs of upgrading, and we can prioritize these items for our client work. We actually learn from each migration that we do and we can utilize those skills in future upgrades.    

Hire A Team

Obviously, I am going to tell you to hire CakeDC for upgrading, but truthfully that is because we have done many upgrades (and learned the mistakes / solutions to many problems that occur) and have well experienced developers in most time zones  This allows us to have great relationships with our clients, and stay in constant contact. The biggest benefit is that hiring externally will not disrupt your routine, and it gets the upgrading / migration done a lot quicker. We are all tempted with distractions, prioritized work, etc. Save time, and probably money by looking into a company to do the work for you, and I promise you will thank me later.    Another shameless plug: see our development service details HERE. Need more reason to upgrade? Check back to read next week’s blog for the many benefits.   

CakeFest 2021 Decisions

Well… 2021 is already feeling a little 2020ish to me, what about you? While I had high hopes of things being back to normal as far as travel, events, etc. It seems as though we still have a ways to go in that department.  

Difficult Decisions

Our events are no exception to this. While virtual CakeFest was a great success, I think that the CakePHP team, as well as the community had hoped for an in-person event… sooner, rather than later. Everyone is missing the adventures and camaraderie that physical meet-ups bring. Unfortunately, we may be waiting a little longer. The team couldn’t stand to make the tough call on the event alone, without consulting with the community.  

The Community Has Spoken

So, CakePHP took to the polls. The question was posted via social media, and included in the January newsletter: Should CakeFest be virtual or in-person (Los Angeles, specifically)? The consensus was no surprise, and 85%+ of bakers voted for a virtual event this year. One follower mentioned that he “wasn’t ready to risk the event not happening at all, so a virtual event is better than no event”. I couldn’t agree more.    A virtual conference was uncharted territory for CakeFest planners and attendees, but in my opinion.. it came together so wonderfully, that it is hard to be disappointed that it will be happening again. So here’s to gathering once again from the comfort of your own space, and hoping that everyone remembers to have their cake ready! Mark Story can even (virtually) cut it for you if you prefer.   The call for sponsors and speakers will be opening soon, so make sure to contact the CakePHP / CakeFest team with any questions you may have ahead of time.  Planning on attending? We would love to hear from you! What are some topics that you would like covered in the workshops or talks? EMAIL US HERE.   *Digital hug*  

Baking Smarter, Not Harder in 2021

After the year we had… our new motto should be work smarter, not harder, in 2021? Am I right? Luckily, CakePHP community and core members are extremely helpful and constantly working to make baking easier. Here are some things that will assist you with your CakePHP projects….

Plugins:

I recently wrote a blog featuring some of the best (voted by the community) CakePHP plugins - you can see it HERE. A full catalogue of CakePHP plugins is available at https://plugins.cakephp.org. It is no secret that plugins are essential for developers. CakeDC has a few of our own as well, you can get details at:  https://www.cakedc.com/plugins. The good news is, if you don’t see one, but have a great idea, you can build and release your own! To learn more about this process, Jose Gonzalez explains it in his CakeFest 2021 Talk.     Lots of other videos / talks / tutorials are located in the CakePHP Youtube channel as well.
 

Tools:

If you follow us on social media, we highlight a lot of tools released from the community.  One of the most popular is the debugging tool: https://book.cakephp.org/4/en/development/debugging.html A commonly used one is to help updating your composer.json while upgrading https://toolbox.dereuromark.de/utilities/upgrade   You can see more on THIS cakePHP tools list from Dereuromark!
 

Support:

I talk about support channels a lot… because well… what is open source without them? Every time I take a virtual stroll to the slack channels, I am amazed at the participation and interaction between community members. It’s like having your own development team available anytime you need them. Rest assured that if you have an issue that's causing a blocker, someone in the chat will (most likely) have a solution. A full list of support channels was listed in our last blog, but if you missed it, here you go: Discourse forum: https://discourse.cakephp.org Stack Overflow: https://stackoverflow.com/tags/cakephp IRC: https://kiwiirc.com/nextclient/irc.freenode.net#cakephp Slack: https://cakesf.herokuapp.com
 

The Book:

If you’re a veteran baker, you already know this. However, this wouldn't be a helpful blog without mentioning the all mighty book… The CakePHP bookThis is where you should start on your cake journey… read it… read it again. Then, reference back to it when you need it. There is an average of 46k users utilizing the book monthly (184k sessions). That should speak for itself.
 

Newsletter:

The CakePHP team releases a newsletter each month. This is a good resource if you’re looking to catch up on a month’s worth of news in one place.  Usually included is: releases, helpful tools, training/event dates, specials, surveys, and more.  You can see previous newsletters & subscribe HERE.   I will close this with a shameless plug: if you want to work a whole lot smarter this year, let someone else do the work for you. Check out all of the CakeDC services offered at cakedc.com/services.    Here’s to 2021 being a lot easier… more peaceful… and tasty!  

Saying Goodbye To 2020 Is A Piece of Cake

I never thought that I would be so excited to say… the year is coming to an end. What a year it has been. Let’s focus on some good things that happened for us this year.

CakePHP Community

Our team worked as closely as ever with the CakePHP community. We have hosted training sessions and multiple online meetups - for which we had consistent attendance and involvement. We have enjoyed getting to know each baker that attends and interacts with us. It was a great year for releases, too. If you follow the social media pages, you’re up to date with all of the new features and tools that are released in real time. Not to mention new and updated plugins. You can see all of the latest releases in the BAKERY.  

CakeFest

While we usually get to travel to some amazing city in the world and meet with the attendees in person, clearly that was not going to be an option this year. For the first time ever, the event was held virtually. Being so involved, and responsible for the success of the event, was stressful and frightening to say the least, but alas…it came together wonderfully.  We were able to have attendees that may not have been able to join us otherwise, and the participation was unprecedented. I am so thankful for the wonderful sponsors, speakers, attendees, and contributors that made the event possible.  In case you didn’t know, all of the CakeFest 2020 videos have been released. You can view them in the CakeFest archive, or on the CakePHP Youtube channel. Don’t forget to subscribe to the channel, and I will tell you why later.    Now… what can be expected in 2021? LOTS!

Increased Involvement

We want to expand the kitchen, if you will. We have an amazing group of core developers, and they would love to have more involvement from the community. If you’ve ever thought about contributing and getting involved, there are many options, you can check out details HERE.   

More documentation / blogs

Speaking of getting more people involved, this will include blogging. We have so many great plugins, but maybe not enough documentation to support the training on them. The core team is on board and we will all be working hard to provide more documentation for the framework. In fact, we even some some community members that have already volunteered to provide more blog contributions to the bakery. Maybe you’d like to as well?!  

Video Tutorials

One suggestion that we get consistently is that we need more video tutorials. We agree! We are going to be updating our YouTube channel and will hopefully be adding more video tutorials as soon as Q1. We will also make sure that training sessions / meetups will be available to subscribers for playback. We would love to hear your suggestions for content, you can email us at [email protected] and let us know what you’d like to see. 
 

Support

As always, CakePHP has many support channels, and this will not change in the new year. In fact, we plan to make it even easier to connect with other bakers.   Here are some current available support options: Discourse forum: https://discourse.cakephp.org Stack Overflow: https://stackoverflow.com/tags/cakephp IRC: https://kiwiirc.com/nextclient/irc.freenode.net#cakephp Slack: https://cakesf.herokuapp.com
  Want to have your opinion heard? The core team wants to know what you want for CakePHP 5. Please take a moment and fill out a quick SURVEY to let them know.    We can’t wait to bake with you in 2021. Wishing you all a happy holiday season and a very happy new year!  

Baking With Attributes

Tasting the cake with attributes

Attributes is a declarative way to pass information about the behaviors of various elements like classes, methods, properties, and even method parameters in your programs. In fact, attributes are used for adding metadata to existing code, and could be used as a way to reduce visual debt, and this way simplifies how code looks like.  

Defining an attribute

An attribute is simply an object whose class inherits from the Attribute class. However, attributes are not used in the same way as a typical object. They often add some additional semantics about the class or method, or to toggle behavior on or off. Some attributes specify functionality. For example, an attribute may contain a method that defines security behavior.  

Declaring Attributes

The attribute itself may be declared as a class. This is validated only when the attribute is fetched, and not immediately when the code is parsed. A PHP attribute is a class, declared with #[Attribute] attribute. In the following example we define an attribute class which allows us to specify what methods are allowed for controller actions.     Take note that in PHP 8 you can declare properties directly in class constructors, which is really handy for data classes.
 

Consuming reflection API to define meta behaviors

Just defined attributes have not added new code logic. To add new behavior we should implement it. Attributes could be fetched using the reflection API. PHP engine knows about attributes but does not instantiate it’s classes, so we have to do it ourselves. Reflection provides getAttributes() methods to fetch a list of associated attributes.   The following  example shows how we can add permissions checks for controller actions using attributes. In this example, the code is stored in beforeFilter of the controller class itself, but it could be an AppController or more generic solution.    

Where to use Attributes

Here are some areas where web frameworks could use attributes:
  •  Routes definition for the controller methods;
  • Validation rules as attributes for entity properties;
  • Smart object serialization, which defined as properties attributes
  • Security rules defined for classes and methods.
  • Static code analyzers.
  • IDE code hinting.
  The attributes are very handy and powerful, they could reduce visual debt and improve code quality. Hopefully this helps with your future projects!  

CakePHP Query Builder

CakePHP’s  database Query Builder provides a simple to use fluent interface for creating and operating database queries. It can be used to accomplish most database operations in your application, and works on all supported database systems.
Query builders allow us to create database queries that work with any supported database, without having to worry about differences between SQL implementations in the different database systems.


The CakePHP query builder uses PDO parameter binding to protect your application against SQL injection attacks. There is no need to clean strings being passed as bindings.
For creating a Query object in CakePHP, the easiest way is using find() from a Table object. In CakePHP, queries are lazily evaluated,  which means that they are not evaluated until any of the following actions happens: the query is iterated through a foreach, it’s called first(), all(), toList(), toArray(). 
You can check all the SQL queries that CakePHP is generating, you just need to enable the Database Logging. See here:  https://book.cakephp.org/4/en/orm/database-basics.html#query-logging
Let’s do a few samples using the Query Builder - this is the ER diagram of the database that we will be using for the queries. We have Orders, ProductsUsers and Items that will store the products sold in each order and the quantity sold. Let’s create some queries using the Query Builder SQL Functions: https://book.cakephp.org/4/en/orm/query-builder.html#using-sql-functions. SQL Functions as part of the Query Builder are abstractions of  some commonly used SQL functions,  and they allow the ORM to choose the specific implementation your application needs based on the Database that is being used. For example, CONCAT is implemented in a different way in MySQL and Postgres, using concat() function will work if you use MySQL or Postgres   Imagine we want to build a report of the products sold, including the following:

  1. Display the product in the following format “Products.name - Products.description”.
  2. Total of products sold.
  3. Total of products in stock..
  4. Total amount on sold products.
First, we need to build the Query object using find(), this needs to be done from the Table. $query = Table->find();. We want to get a report of the products sold and the current stock. Initially, we would need to build a subquery using ItemsTable where the information related to the products sold is present.  Don’t forget to use identifier() when referencing any column. This will tell us  the items sold per product. 

$itemsQuery = $this->Items->find() ->where(['Items.product_id' => $query->identifier('Products.id')]);

Now, let’s build each query needed for the information required:
  1. Let’s start displaying the  product in the following format: “Products.name - Products.description”. Using concat() we could get it: $query->select([             'display_name' => $query->func()->concat([                 $query->identifier('Products.name'), ' - ',  $query->identifier('Products.description')]),         ]);
  2. Total of products sold. Using sum() we could get it, we just need to sum Items.quantity per each product,  this  is why we use $itemsQuery and then we sum the quantity per each product. $query->select([
      'quantity_sold' => $itemsQuery->select(['sum' => $itemsQuery->func()->sum($query->identifier('Items.quantity'))]),
    ]);
     
  3. To get the income, we need to multiply the Quantity of items  *  Price  and sum all of them.    $query->select([
              'income' => $itemsQuery->select(['sum' => $itemsQuery->func()->sum($query->newExpr('Items.quantity * Items.unit_price'))
                ])]);
     
  4. Stock. to get the stock we need to take advantage of the quantity_sold we just got in #2, and subtract it from the real quantity Products.quantity. For getting this, we would need to create a subquery in the FROM clause using the previous queries, and then subtract in the target query something like quantity - quantity_sold. $products = $query->cleanCopy()->select([
                'id' => 'ProductDetails.id',
                'price' => 'ProductDetails.price',
                'quantity' => 'ProductDetails.quantity',
                'display_name' => 'ProductDetails.displaye_name',
                'quantity_sold' => 'ProductDetails.quantity_sold',
                'income' => 'ProductDetails.income',
                'stock' => $query->newExpr('ProductDetails.quantity - ProductDetails.quantity_sold'),
            ])->from([
              'ProductDetails' => $query->cleanCopy()->select([
                    'id' => 'Products.id',
                    'price' => 'Products.price',
                    'quantity' => 'Products.quantity',
                    'display_name' => $query->func()->concat([$query->identifier('Products.name'), ' -  ', $query->identifier('Products.description')]),
                  'quantity_sold' => $itemsQuery->select(['sum' => $itemsQuery->func()->sum($query->identifier('Items.quantity'))]),
                  'income' => $itemsQuery->cleanCopy()->select(['sum' => $itemsQuery->func()->sum($query->newExpr('Items.quantity * Items.unit_price'))]),           ])
        ]);
     
Notice that we are using cleanCopy(), this is useful when the same Query object is affected previously by a select(), from() or where clauses, if you run this same example without using cleanCopy() you will get unexpected results.  The SQL query generated is this: SELECT ProductDetails.id AS id, ProductDetails.price AS price, ProductDetails.quantity AS quantity, ProductDetails.display_name AS display_name, ProductDetails.quantity_sold AS quantity_sold, ProductDetails.income AS income, (ProductDetails.quantity - ProductDetails.quantity_sold) AS stock FROM (SELECT Products.id AS id, Products.price AS price, Products.quantity AS quantity, (CONCAT(Products.name, :param0, Products.description)) AS display_name, (SELECT (SUM(Items.quantity)) AS SUM FROM items Items WHERE Items.product_id = (Products.id)) AS quantity_sold, (SELECT (SUM(Items.quantity * Items.unit_price)) AS SUM FROM items Items WHERE Items.product_id = (Products.id)) AS income FROM products Products) ProductDetails
CakePHP QueryBuilder gives a ton of possibilities to create queries with clean and robust code. So go play with it and enjoy!  

Are you ready for PHP 8?

In just two days we will get a new PHP release, PHP 8. It’s been almost  5 years since PHP 7 was born and now we are about to enjoy the new major version, which will include some breaking changes and performance improvements.   It comes with a lot of new features, including:  

  • PHP JIT
  • Union types
  • Named arguments
  • Attributes
  • Match expression
  • Constructor property promotion
  • New static return type
  • New mixed type
  • Throw expression
  • Inheritance with private methods
  • Weak maps
  • Allowing ::class on objects
  • Non-capturing catches
  • Trailing comma in parameter lists
  • Create DateTime objects from interface
  • New str_contains() function
  • New str_starts_with() and str_ends_with() functions
  • New fdiv() function
  • New get_debug_type() function
  • New get_resource_id() function
  • Abstract methods in traits improvements
  • Object implementation of token_get_all() 
  • Variable syntax tweaks
  • Type annotations for internal functions externals
  • ext-json always available
  We will explain some of these features in future posts.   Remember that PHP 7.4 active support will remain until November 2021, with security fixes until November 2022. PHP 7.3 active support is almost over and the team will provide security fixes for 1 more year. Finally, PHP 7.2 is already out of active support, and almost out of security fixes (in 5 days). If you want to check PHP versions and support you can go HERE.   So, Are you ready for PHP 8?  

The Making of a Marketing Plan

Listen, although 2020 felt like it lasted 25 years, it’s still hard to believe that we are wrapping up this roller coaster of 12 months.  As companies prepare for 2021, crossing their fingers and wishing for a better Q1… it is important to start thinking about marketing strategies and plans for the next year. Without ideas and a solid goal for your company, it is very unlikely that things will change.   Reasons that making a marketing plan is important:  1. It organizes your goals and provides clear plans of actions to achieve them  2. It keeps everyone on track and on the same page  3. Promotes motivation and accountability
  I know making a marketing plan can sound time consuming, and a little complex, but it doesn’t have to be! I am going to walk you through the steps of making clear cut goals and plans for 2021 (with some actual examples!).  

1. Brainstorming

Our team is great at making notes of things that need attention, whether it's good or bad. We keep open lines of communication on things that are going well, or may need some extra work. It is important for everything to bring their ideas together, no matter how big or small.  I suggest keeping a notepad with things / ideas you have for your team moving forward, and organize them in a way to present to your marketing team.  

2. Team meeting

Now it is time for a group session to compare ideas, talk about what should be the priorities and get approval on anything needed. These meetings are super beneficial, because it is always refreshing to see if your team’s ideas mimic yours, or perhaps they even have some additional great ideas.   

3. Start building your plan

There are ample amounts of templates and checklists that you can find online to ensure that you’re including important information on your strategy plan. Some of the things I recommend including are:
Of course your main table of contents - easy to view for your team     Company mission - WHO ARE YOU?  
  Product Overview - what are you offering your clients?     Goals / Challenges - we all have them, don’t be shy  

Target market - Who are you working for?       Expansion Plan - how will you make it to the next level?   Upcoming Actions - Making a clear timeline for the next year. It is important to make the timeline obtainable... in other words, don’t make goals that are impossible to meet.   Other important topics include additional small actions, goal timeline, campaign calendars, advertising outlets, social media platforms (and the importance, utilization for each one).  

So making a powerpoint or pdf presentation for your team will allow all of the ideas and goals  to come together and be available in one place. I am a big checklist type of person, so in addition to my marketing plan, I always create a document.   

4. Create a spreadsheet

A spreadsheet doesn't have to be fancy, but it holds the team accountable, and we are able to make notes so that we can track the status of certain actions. This also helps me stay on track, and know what actions need to be executed next.    Something like this for internal works just fine:  
 

5. Budget & Execution 

It is extremely important that your team supports the marketing efforts. It is also important to know what your marketing budget will allow. Will you have additional funds for new goals? Will you need to reduce funds on other outlets to allow for new ideas? These are things that will need to be discussed with your financial department.   This is a good reason to create a marketing metrics / budget spreadsheet to track these items. I will share my examples on this in a future blog.    So, once your team is on the same page, and they have clear goals…. IT’S GO TIME. Start working on your plan of actions and preparing to let them fly. For us, some of our goals will take some prep work, so we are gearing up in Q4. 
  Hopefully, you have helpful ideas that you implement on your marketing plan… maybe it’s something I haven’t thought of (i’d love to hear yours! Email me - [email protected]). Either way, I wish everyone good luck on their strategies, and may all of your goals come true in 2021. If you’d like more insight on any of the ideas I have included, feel free to reach out, I’d be happy to chat!   

Baking With Traits

Traits are a mechanism for code reuse, the convention traits in CakePHP are suffixed with Trait so they can be discernible from classes or interfaces. Our book has a basic sample of Trait. For me, writing code with Traits it's not a regular daily job, but last week I found myself writing a Trait for handling the Theme of an Application.  We need to define the theme on AppView and AppController, and we don't want to repeat ourself:  Beyond re-use code, we can use Traits to separate our code by responsibility.  We like this approach so much that our Users Plugin utilizes it.:   Basically, instead of creating a regular controller with many methods, we create Traits and group the actions by domain business. Sometimes we need to override the functions, and we want add our custom logic after -before or replace the function on Traits: If you wanna bake Traits more complexly I recommend you check out the PHP manual… there,you can see how to fix conflicts, change the visibility of methods and so much more.
That's all bakers! I hope you’ve found this information to be helpful!  

Using CakePHP ORM in your app

CakePHP ORM in your app

We all know that CakePHP is a Full Stack framework, but you may not know that you can pick some of the components and use it in your app when you need. The ORM is not the only one available - you could also have filesystem, validation, utility, core, collection, database, cache, event, form, log, datasource, console and i18n. In this article, we are going to show how to use the ORM component in your slim framework app. You can find the component at: https://github.com/cakephp/?q=read&type=&language=  

Why should we use the componentes

You may be asking why to use as component instead of using the framework as it is, and one of the reasons would be that you already have an application, perhaps using slim framework, and now you need to retrieve data from database. This would be a good moment to use a lib to help you, and here is where cakephp/orm comes in handy. With the componentes you can now solve things with your knowledge in CakePHP, even when your application was not built with CakePHP.  

Setting up cakephp/orm in a slim application

The code used in this article can be found at: https://github.com/CakeDC/slim-cakephp4-packages We could use the package in any PHP application, but for this article we are going to use a slim application skeleton https://github.com/slimphp/Slim-Skeleton. In this app we’re going to change the routes /users and /users/[id] to fetch data from database instead of in-memory data.  

Install the package with composer

We are going to install the version 4.0 of the ORM package:   composer require cakephp/orm:~4.0  

Update config

The app uses the file app/settings.php to set up the main configs, so we need to add a config for database and set cakephp’s App.namespace config. First: add this line after the use declaration. Don’t worry about this config now. We’re setting this to avoid error with PHP 7.4.   Configure::write('App.namespace', 'App');   Then add your database config key inside settings array - in this case we’re using mysql database from a docker service:               'database' => [                 'className' => \Cake\Database\Connection::class,                 'driver' => \Cake\Database\Driver\Mysql::class,                 'database' => 'my_db',                 'username' => 'root',                 'password' => 'secret',                 'host' => 'mysql',             ]   See https://github.com/CakeDC/slim-cakephp4-packages/blob/main/app/settings.php  

Add TableLocator to app dependencies

The app uses the file app/dependencies.php to configure the container of dependencies, and this is a good place for us to define TableLocator as dependency since we normally would use it In my places. Let’s add this inside $containerBuilder->addDefinitions:   \Cake\ORM\Locator\TableLocator::class => function(ContainerInterface $c) {             $settings = $c->get('settings');             \Cake\Datasource\ConnectionManager::setConfig('default', $settings['database']);               return new \Cake\ORM\Locator\TableLocator();  }   See https://github.com/CakeDC/slim-cakephp4-packages/blob/main/app/dependencies.php     This service gets the settings we defined before,sets the configuration to CakePHP, and returns an instance of TableLocator. We could use this service in any route action with:    $locator  = $this->get(\Cake\ORM\Locator\TableLocator::class); $users = $locator->get('Users')->find()->all()->toArray();   But for this app it will make sense to use the TableLocator in a custom persistence class.  

Using the ORM to fetch data

Now, we are finally going to replace the current way of retrieving data to be able to use CakePHP OR. Since our idea is to have a minimum impact in the app, the best way for this app is to replace the current UserRepository. Keep in mind that you could use the following steps with any other class you have.   Create a new persistence class DatabaseUserRepository: Create the class at src/Infrastructure/Persistence/User/DatabaseUserRepository.php Define a constructor method with tableLocator parameter       public function __construct(\Cake\ORM\Locator\TableLocator $tableLocator)     {               $this->tableLocator = $tableLocator;     }          Now we can use the tableLocator to fetch data:         $this->tableLocator->get('Users')->find()->all();       $this->tableLocator->get('Users')->get(10);       ////   To make the app work correctly, we need  to add the required method findAll  and findUserOfId   See: https://github.com/CakeDC/slim-cakephp4-packages/blob/main/src/Infrastructure/Persistence/User/DatabaseUserRepository.php      Now that the repository persistence class was created, we need to connect using dependency injection. Update the UserRepository::class entry in repositories with:   UserRepository::class => \DI\autowire(\App\Infrastructure\Persistence\User\DatabaseUserRepository::class),   https://github.com/CakeDC/slim-cakephp4-packages/blob/main/app/repositories.php   That’s it! Now we can access /users and see the users stored in our database.   I hope you’ve found this information to be helpful! Let us know! For more information check out: https://github.com/cakephp/orm.

Playing with the new CakePHP Queue

One of the topics discussed in the community is the benefit of a unified, officially supported, CakePHP Queue plugin. Queues are used in most of the projects nowadays and are a central utility plugin. During the CakeFest 2020 event, there were also a couple direct references from speakers: (https://speakerdeck.com/josegonzalez/building-and-releasing-a-cakephp-plugin/?slide=15c) and this comment from Mark Story: https://cakesf.slack.com/archives/C172CS4TE/p1602257791377500.   This motivated me to take a deeper look at the cakephp/queue plugin and write this blog post.   Here at CakeDC we've been using queues for a looooong time. Initially in CakePHP 2, we've used plugins like CakeResque with redis or custom workers tied to Amazon SQS queues. Then in CakePHP 3 & 4 we've been using mostly https://github.com/josegonzalez/cakephp-queuesadilla with redis or mongodb backends. https://github.com/cakephp/queue   First thing would be setting up the plugin in your project, we are going to use the example project we used in CakeFest 2020: https://github.com/cakephp/cakefest2020/#using-docker   So after setting up the project and running it via docker compose, we can proceed to setup the plugin via composer. We will need to add it as a repository and set  

Install via composer

  After the first release it'll be much easier, but for now you'll need to add the package to your composer.json   "repositories": [         {             "type": "vcs",             "url": "https://github.com/cakephp/queue.git"         }     ]   Then do composer require cakephp/queue -W   And install some transport as stated in the official documentation https://book.cakephp.org/queue/1/en/index.html#installation composer require enqueue/redis:^0.9 composer require predis/predis:^1   Ensure your redis server is up and running, you can check the commands sent to your local redis server using redis-cli monitor   Now we are ready to configure the queue, we'll create 1 default queue adding this to the config/app.php file       'Queue' => [         'default' => [             'url' => 'redis:',         ],     ],   Add a Job using `bin/cake bake job Example` and add some code to the execute method       public function execute(Message $message): string     {         $data = $message->getArgument('data');           // do some long operation with data         Debugger::log($data);         sleep(2);           return Processor::ACK;     }   I've added a command utility to enqueue a test message bin/cake bake command addJob       public function execute(Arguments $args, ConsoleIo $io)     {         $callable = [ExampleJob::class, 'execute'];         $arguments = ['id' => 1, 'data' => ['some' => 'data']];           QueueManager::push($callable, $arguments);     }   And finally we can start our worker using bin/cake worker to pull jobs from Redis and process them using the ExampleJob::execute method   Here's all the example code created: https://github.com/cakephp/cakefest2020/tree/feature/cakephp-queue - for your reference.   Please note the plugin is still a work in progress and there is no stable release as of now.  It's looking great so far and we plan to include it in our next projects!  

Best CakePHP Plugins

Members of our team had the privilege of helping with CakeFest 2020 this year. One added virtual feature was the giveaways from CakePHP, these were done in the form of fastest-to-answer, trivia, or participation (random draw).  One of the giveaway games was to share your favorite CakePHP plugin but like, how do we only pick one, right? Anyway… There was a lot of participation in this giveaway! A few people even named our CakeDC Users plugin as their favorite *cue blushing face*. But in all seriousness, I thought it would be a good idea to share with you some of the plugins that were named most useful/helpful by CakeFest attendees this year….   Like I mentioned, the CakeDC users Plugin: https://github.com/CakeDC/users Queue Plugin: https://github.com/dereuromark/cakephp-queue Bake: https://github.com/cakephp/bake DataTables: https://github.com/fheider/cakephp-datatables CakePHP-tools: https://github.com/dereuromark/cakephp-tools Authentication: https://github.com/cakephp/authentication CakePHP-image: https://github.com/josbeir/cakephp-image Fixturize: https://github.com/lorenzo/cakephp-fixturize CakePHP File-Storage: https://github.com/burzum/cakephp-file-storage Crud: https://github.com/FriendsOfCake/crud IDE Helper: https://github.com/dereuromark/cakephp-ide-helper Asset-Compress: https://github.com/markstory/asset_compress CakePHP Debug Kit: https://github.com/cakephp/debug_kit Plum-Search: https://github.com/skie/plum_search CakePHP API: https://github.com/cakedc/cakephp-api/ Bootstrap UI: https://github.com/friendsofcake/bootstrap-ui Trash: https://github.com/usemuffin/trash   You can check out the full list of CakePHP Plugins at Plugins.CakePHP.org.  Have you been utilizing these tools? If not, it may be a good idea to start… while each of these serve their own purpose, using all of them can make your baking process a lot easier.    Perhaps your favorite didn’t make this list? Tell us about it… email HERE. Or, tweet us @CakeDC, @CakePHPThanks for baking!  

CakeFest 2020 recap

Taking a deep breath….. We have made it through another successful CakeFest event.    We didn’t know exactly what to expect with a fully virtual event, as it opens the door for a list of things that can (and most likely will) go wrong. Would the speakers show up? Would the internet connections keep things from running smoothly? Would attendees enjoy the information?   The answer to all of those questions is yes.    The lineup this year was amazing, and we had speakers from 6 different countries! With the ever changing way of life, our team wanted to have a diverse group of speakers, with some talking about some pretty serious subjects - like Dr. Jennifer Akullian and the mental health issues faced in the tech world. Jen allowed for questions and how-to-handle scenarios, and worked through some tough issues with attendees. Workshops from Mark Story, Jorge Gonzalez, Mark Scherer and Jose Lorenzo provided incomparable information while building projects in real time. All of the talks provided useful information that we hope all attendees will take with them as they bake in the future.    Now, does all of this bragging mean we didn’t have any issues? No. As I said in our opening, I think our group is pretty awesome and perfect, but the fact of the matter is, no one is. When bringing people together from all over the world, it is hard to test and check every connection multiple times. We had our fair share of internet lag, connection problems and audio issues. You know what we did? We worked together, fixed it, switched around the schedule and made it happen.   Virtual CakeFest 2020 was a great success, and exceeded our expectations. We were able to gather bakers from all over the world, in real time, and host a live event! I couldn’t believe how interactive the audience was, and everyone is still baking together in our #cakefest chat channel. I hope everyone is as impressed with the turn out as our team is. I know what you’re thinking… when will the recordings be released. We are working on uploading, editing and releasing the videos ASAP. While we tried to find the best universal timezone, we understand that other obligations kept some from attending, and we want to share these videos with you quickly, so know that we are working on it.    To our attendees: THANK YOU. Thank you for joining, supporting our framework and keeping CakePHP alive.   

I would like to thank all of our speakers:

  Remy Bertot  Junichi Okuyama Mark Story Jorge Gonzalez Jose Lorenzo Mark Scherer Jose Gonzalez Cal Evans Ed Barnard Jennifer Akullian Mariano Iglesias Chris Nizzardini Juan Pablo Ramirez
 

A HUGE THANK YOU TO OUR SPONSORS:

   Cake Development Corporation
  Passbolt 
  Marks Software
  RingCentral  


  Here’s to planning next year’s event to be even bigger and better!  

How to take a rest in five minutes

There are a lot of toys these days. Let me show you one very simple and powerful brick for your next revolutionary invention. Let's assume that you're either:

  • A curious person, and you like to play with things you don't know, just for the case
  • A frontend developer with no PHP coding experience, and your javascript components could use some dynamic backend json resource. Maybe you want to do this without playing with all mocking options or Node.js modules out there...and you don't want to set up MySQL database, user, grant permissions and all that stuff
  • building dynamic user interface, and your code needs to be aware of continuously changing structure of databases using unpredictable table names
  • A creator of a wireless network of IoT devices or swarm of flying educational robots. Or, looking for some stable and performant data backend running on your central Raspberry Pi Zero W with tmpfs mounts and ridiculously huge memory card, while sniffing around for bluetooth signatures
  • aware of services like ngrok and wanting to consume payloads of some IFTTT webhooks locally. Or, allowing a friend with Postman to access and/or feed up your database created (or temporarily exposed) just for that reason.
  • Having a rich html application and flirting with the idea of full blown CakePHP backend running in kiosk mode of the DraftCode application right on your iOS device
  • able to pack a PHP application as a single file Phar archive. For example: to simplify all sorts of domain logic/responsibility distribution across bazillions of machines spawned on demand and utilizing jq in your provisioning scripts
  • praying for headless access to any database that your CakePHP application is able connect to, bypassing implemented validation, callbacks, events, and even sneaking through your authentication/authorization backdoor if you want to
  • going to try following example right away, or at least very soon
If your machine meets the CakePHP Requirements, and you have composer in your $PATH then we are good to go for a CakePHP application using SQLite database accessible through REST. This would have obvious api goodies like CRUD, CORS, HATEOAS, versioning, list, describe, relations, sorting and pagination included by default.

Clock is ticking, time to rest with some book(s)

I don't know how much time of the rest limit we lost on the preface (quick learners are quick readers), but don't worry, unless you are on the slow internet connection and packagist is taking a break - we are almost done. We have a clear picture of what we're going to create, so the rest is a piece of cake.
  • create a CakePHP 4.x project named rest with CakeDC/Api plugin unlocked and loaded:
composer create-project \ --prefer-dist --no-interaction \ cakephp/app:~4.0 rest cd $_ composer config \ minimum-stability dev composer require \ cakedc/cakephp-api:~8.0
  • Unlock and load! Auth bypass, "allow all" switch (don't try this at home)
cp vendor/cakedc/cakephp-api/config/api_permissions.php.default \ ./config/api_permissions.php bin/cake plugin load CakeDC/Api
  • manually (meh, we should be resting now) configure Database.default connection in the file config/app_local.php
'database' => TMP . 'rest.sqlite', 'driver' => 'Cake\Database\Driver\Sqlite',
  • create example table books in the database and start local server
bin/cake bake migration create_books \ title:string:unique \ description:text \ price:integer:index \ available:boolean:index \ created \ modified bin/cake migrations migrate bin/cake server Open http://localhost:8765/api/books in your browser to see the (empty) list of your books, then pick some RESTful Route and take a rest from the back end, even without backend coding, scratching who knows where, etc. You maybe have some SQLite databases laying around, and that would be also worth a try. I forgot to remind you to stop that 300s timer, sorry. You will get lost in time as well, once you'll realize what all is possible with the CakeDC/Api plugin using little to no configuration, and what dimensions are opening to you. If you combine its powerful multilayer services approach with solid implementation of your custom ORM classes embraced by CakePHP core and conventions, the results are amazing. Oh, and a quick note for CakePHP 3.x developers - we like you, but please take your time to upgrade your toolset. Feel free to ask us for help, or use following warranty-limited commands: composer create-project \ --prefer-dist --no-interaction \ cakephp/app:^3.9 rest composer require \ cakedc/cakephp-api:~7.0 bin/cake plugin load -b -r CakeDC/Api

What's next

CakeFest 2020 of course. I hope you all are as excited as we are, together in these hard times. Be safe and take care, folks! And rest too, even if it's a quick one :-)

CakeFest Insider

In case we haven’t reminded you enough lately, CakeFest 2020 is less than a month away. While we have recently hosted a few virtual meetups, a fully virtual conference is uncharted territory for our team. I like to look on the bright side of things, so I will say how excited I am that bakers from all over the world will be able to join in and participate this year. Obviously, with international travel, this hasn’t always been the case for individuals. So my last CakeFest blog, I went into details of what to expect, and how the conference will (hopefully) run - smoothly. However, we’ve had a lot of emails and interest in hearing about what topics will be covered. Our lineup is excellent this year - so we wanted to share some things to look forward to:  

SPONSORS

First, we have to give a shout out to this year’s sponsors Cake Development Corporation  Passbolt Mark’s Software  RingCentral Companies that support Open Source are essential for our communities to move forward and grow!   

SCHEDULE

Day 1 will feature our popular workshops. These sessions are different than normal conference talks because they are basically training sessions to help grow your recipe book. You can see examples of previous years HERE. There will be basic workshops, as well as advanced during the full day session. We have condensed this year’s duration, so what is normally 2 days of workshops will be done in 2 hour sessions by each baker.  Mark Story, Jorge Gonzalez, and Jose Lorenzo are back. This year, we’ve also recruited another core member, Mark Scherer… you may be familiar with Mark from hosting many of our virtual meetups.  Topics that our core members MIGHT include are (these are being discussed): CakePHP 4.x, as well as project examples -  a repost builder, a headless micro cms, a media server to upload/download cache files from S3. The speaker’s will build through a project with you, answering questions as they progress.  Have an idea you’d like the workshops to include? Email us! [email protected].
  Now, day 2. This year, we decided to go ahead and try a few new things. Of course being 100% digital, condensing times, and some topics and speakers that may be unexpected. I personally invited some speakers that I thought could bring something fresh to the tech conference table.  One of these being OSMI (Open Source Mental Illness). I wanted to bring mental health importance to light, and this group is doing amazing things for the development world. Mental health doesn’t have to be a taboo subject. Dr. Jennifer Akullian will be talking about mental health, stress, and burnout in the tech industry. In addition to an overview of the research, distinctive considerations of the industry we work in will be discussed, as well as how to improve the management of common stressors in technology during an incomparable time in the world. We will also hear how some people got their start, like Michael Hoffman, and learn how to build solid architecture with CakePHP Plugins thanks to Ed Barnard. Ever wondered how to release your own plugin? Jose Gonzalez will shed some light. We are also delighted to have one of our involved Japanese community bakers, Junichi Okuyama, joining us as a speaker this year talking about helpful tips that he has learned for baking with CakePHP. Our keynote will be given by our diamond sponsor representative from Passbolt, Remy Bertot.  Other talks will include: well known podcast host Cal Evans talking about all of the cool things that can be done with PHP's built in DateTime math, Mariano Iglesias,  core members Mark Story, Chris Nizzardini and Mark Scherer. Popular contributors Juan Pablo Ramirez and Nicolas Masson will join us and share more details about CakePHP fixture factories.   You can see the full schedule HERE, and plan your attendance accordingly. 
 

SLACK CHATS 

We will also have slack chat rooms for attendees. This will give everyone the opportunity to interact with other watchers as well as speakers. Questions are welcomed before, during, and after the event. We will have team members monitoring the chat and trying to get all questions answered as soon as possible.   Slack channel tag: #cakefest  So basically, have a coffee and a chat with other attendees and presenters.    Have you purchased your ticket yet? WHAT ARE YOU WAITING FOR?    

Upgrading to CakePHP 4

As you know, CakePHP announced the version 4.x last December.I recommend that you consider upgrading your applications to the next version, to keep up to date and get all the benefits. Now, let's see how to bake!  

Step 1: Upgrade PHP

First things first, if you are not running on PHP 7.2 or higher, you will need to upgrade PHP before updating CakePHP. CakePHP 4.0 requires a minimum of PHP 7.2.  

Step 2: Upgrade Templates and Resources

There is an upgrade CLI tool for rename and moving the templates and resources:   Templates and Resources must have been moved and renamed, check the result below: * This project doesn't have Resources files   Now, let's create a new constant for Resources on /config/paths.php: Finally, update the paths on config/app.php:  

Step 3: Upgrade CakePHP

The next step is optional (and the Migration Guide included this) - run the rector command to automatically fix many deprecated method calls: The rector applied on codebase some return type declarations: https://github.com/rafaelqueiroz/cakephp-upgrade-sample/commit/d7e5c2ecc5dc28045700a270721f07098a8e189c?branch=d7e5c2ecc5dc28045700a270721f07098a8e189c&diff=split Pay attention: It is important to apply rector before you upgrade your dependencies.   Upgrade CakePHP and PHPUnit: PHPUnit can be upgraded easily. Most of the time, the --update-with-dependencies doesn’t work with me for CakePHP: The root of the issue is the packages using Caret Version Range, so let’s update debug_kit, migrations and bake using editor:   Here we go:   Now, let see how the project looks: Here, we have few deprecations and warnings. Do you remember I mentioned the rector is optional? So, the question is the rector and it's not always able to handle these issues.   I will use the PHPStan to fix this - we will install with composer: Now, we can run the phpstan analyse and fix the issues:   It's up to you how much effort you will put in with PHPStan issues. I recommend fixing everything. For this post, I did fix only what was needed to run the project after the update, you can check the fixes on this commit.   After the last fixes, the project is running well:  That’s all? No. But we upgraded CakePHP? Yes. Real applications probably use many plugins, and if these plugins don't have a version for CakePHP 4, you will need to update. Depending on the size and level of complexity of the project, the upgrade could be hard, but never impossible.    If you do not feel confident or your company would like to outsource support for this, don't hesitate to contact us at Cake Development Corporation. Our team is offering a full upgrade from CakePHP 2/3 to CakePHP 4. This will be a migration of your current application code to make it compatible with CakePHP 4 features, plugins, security settings, etc. We will be doing these migration services for a special rate - something we have never done before! Learn more about our Upgrade Services You can check the codebase of the examples on this repository. The branch upgrade has all steps by commit.  With every release CakePHP gets better, and version 4.x is no exception. There are many benefits that come with upgrading, and it makes baking a lot easier.

We Bake with CakePHP