Kaizen #84 - PHP SDK [Part I]

Kaizen #84 - PHP SDK [Part I]

Hello and welcome to another Kaizen week!

In this week's post, we'll show you how to get started with Zoho CRM's PHP SDK, and walk you through the configuration and initialization process.

PHP Software Development Kit

PHP SDK allows you to create client PHP applications that can be integrated with Zoho CRM effortlessly. It serves as a wrapper for the REST APIs, thus making it easier to use the services of Zoho CRM.

Why PHP SDK?

Easy authentication: You don't have to worry about manually managing authentication because the PHP SDK takes care of generating access/refresh tokens for you.
Easy and Efficient data exchange: With the PHP SDK, you can easily exchange data between Zoho CRM and your client PHP application, where the CRM entities are modelled as classes. You can declare and define CRM API equivalents as simple functions in your PHP application.

Prerequisites 

  • The client app must have PHP 7 or above with a cURL extension. cURL extension is used to connect and communicate with the Zoho CRM APIs.
  • The client app must have the PHP SDK installed through Composer

How to start using the PHP SDK?

  1. Prerequisite : Register your application with Zoho CRM.
  2. Install the PHP SDK.
  3. Knowledge Base : Token Persistence
  4. Configuration 
  5. initialization.

1. Register your application with Zoho CRM

Registering your application with Zoho CRM is a mandatory step in order to authenticate and authorize API calls using the OAuth2.0 standards.
  1. Go to https://api-console.zoho.com
  2. Click on Get Started or +ADD CLIENT.
  3. Choose the Client Type.
  4. Fill in the necessary details and click CREATE. Once you successfully register your self-client, you will receive a Client ID and Client Secret.

2. Install PHP SDK 

1. Install Composer, if not already installed. Please check the corresponding link for installation instructions.

2. Install PHP-SDK using Composer
  • Navigate to the workspace of your client app.
  • Run the following command in the workspace. Upon successful installation, the system will create a package named vendor in the workspace of your client app.   Note : This command installs SDK for API v2.1.

    composer require zohocrm/php-sdk-2.1

3. To use the SDK in your project, add the following line in your project PHP files. This loads and includes our PHP-SDK library in your project. If you skip this step, you will get a fatal error in response due to the missing libraries.

require 'vendor/autoload.php';

3. Token Persistence

Token persistence refers to storing and utilizing authentication tokens provided by Zoho, enabling the SDK to refresh the access tokens without the need for user intervention. The SDK offers three types of persistence - File, DB, and Custom - with file persistence being the default method. 
The persistence is achieved by writing an implementation of the inbuilt TokenStore interface, which has the following callback methods. 

Method
Description
getToken($user, $token)
Invoked before firing a request to fetch the saved tokens. This method returns an implementation of Token interface object for the library to process it.
saveToken($user, $token)
Invoked after fetching access and refresh tokens from Zoho. This method saves the token details.
deleteToken($token)
This method is used to delete the given token details.
getTokens()
This method is used to retrieve all the stored tokens.
deleteTokens() 
The method to delete all the stored tokens.
getTokenById($id, $token) 
This method is used to retrieve the user token details based on the unique ID.

a. Token Persistence using a Database

Database persistence is a technique that involves storing and retrieving data from a database. If you prefer using database persistence, you can use MySQL. 
Create a table in your database with the required columns. For example, if you want to persist your tokens in a table named token in database named zoho, use the following:
CREATE DATABASE zoho; // use this to create database named zoho
// use this to create a table named token, with the necessary columns
CREATE TABLE token ( 
  id varchar(255) NOT NULL,
  user_mail varchar(255) NOT NULL,
  client_id varchar(255),
  client_secret varchar(255),
  refresh_token varchar(255),
  access_token varchar(255),
  grant_token varchar(255),
  expiry_time varchar(20),
  redirect_url varchar(255),
  primary key (id)
);

In this example, your tokens will be persisted in the token table in your zoho database.

b. File Persistence

File Persistence allows storing and retrieving the authentication tokens from the given file path. The file contains id, user_mail, client_id, client_secret, refresh_token, access_token, grant_token, expiry_time and redirect_url. 

c. Custom Persistence

Custom Persistence refers to a technique where users can create their own method of storing and retrieving authentication tokens. To use this method, users need to implement the TokenStore interface and override its methods according to their own logic.

4. Configuration

Configuration is a critical step in which you set up SDK's configuration details like user authentication, token persistence, logging and API call timeout settings, and more. Listed below are the keys that you define in this step.

Key
Description
user
mandatory
Represents the mail id, which is used to identify and fetch tokens from the File or DB.
environment
mandatory
Represents the data centre details in Domain::Environment pattern.
Domains : USDataCenter, EUDataCenter, INDataCenter, CNDataCenter, AUDataCenter
Environments : PRODUCTION(), DEVELOPER(), SANDBOX()
token
mandatory
Contains user token details. Depending on the tokens, you can choose grantToken flow, refreshToken flow or accessToken flow.
logger
optional
Contains the configuration for logging exceptions and API call information. By default, the logs will be available in the workspace as sdk_logs.log.
store
optional
Contains details for the Token Persistence object. You can choose between DB Store, File Store or Custom Store, and configure accordingly.
SDKConfig
optional
Contains additional configuration details like timeout, autorefresh fields, picklistvalidation, etc
requestProxy
optional
Contains the details of the proxy, if you are using a proxy server to authenticate and make the API calls.
resourcePath
optional
The path containing the absolute directory path to store user specific files containing the module fields information.


Let us discuss how to configure each of them, in detail.
a. user : The user key will be used to store and identify the tokenstore details in the DB or File Storage for token persistence. Create an instance of UserSignature that identifies the current user with the following :
  1. $user = new UserSignature("patricia@zoho.com");
b. environment : The API environment which decides the domain and the URL to make API calls. 
  1. $environment = USDataCenter::PRODUCTION();
c. token : Create an instance of OAuthToken with the information that you get after registering your Zoho client. Depending on the tokens available with you, you can choose one of the following flows. 
Note : You need to generate the tokens (grant/access/refresh) beforehand. 
  • grantToken flow - You should use the grant Token for configuration.
    $token = (new OAuthBuilder())
      ->clientId("clientId")
      ->clientSecret("clientSecret")
      ->grantToken("grantToken")
      ->redirectURL("redirectURL")
      ->build();

  • refreshToken flow -In this flow, use the refresh token.
    $token = (new OAuthBuilder())
      ->clientId("clientId")
      ->clientSecret("clientSecret")
      ->refreshToken("refreshToken")
      ->redirectURL("redirectURL")
      ->build();

  • accessToken flow - You can use the access token to configure in this flow. Please note that the token will not be persisted in this case, and the access token will be directly used to make the API calls.

    $token = (new OAuthBuilder()
      ->accessToken("accessToken")
      ->build(); 

d. logger : Create an instance of Logger Class to log exception and API information. You can set the level you want to log (FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, ALL, OFF), and also configure the file path and file name for the log file.

$logger = (new LogBuilder())
->level(Levels::INFO)
->filePath("/Documents/php_sdk_log.log")
->build();

e. store : Configure your token persistence using this method. If this is skipped, the SDK creates the sdk_tokens.txt in the current working directory to persist the tokens by default.
  • DB Store - Configure the Database details, where you want to store your tokens.
    $tokenstore = (new DBBuilder())
    ->host("hostName")
    ->databaseName("dataBaseName")
    ->userName("userName")
    ->password("password")
    ->portNumber("portNumber")
    ->tableName("tableName")
    ->build();

  • File store - Give the absolute file path, where you want to store the tokens. 
    $tokenstore = new FileStore("absolute_file_path");

  • Custom Store - In this method, you can implement your own method for storing and retrieving the tokens. Please note that to do so, you must implement the TokenStore interface, and override its callback methods (getToken, saveToken, deleteToken, getTokens, deleteTokens, getTokenById). 
    $tokenstore = new CustomStore();

Note :  The corresponding storage will  have id, user_mail, client_id, client_secret, refresh_token, access_token, grant_token, expiry_time and redirect_url. The id is a unique system generated key.

f. SDKConfig : The additional SDK configurations are taken care of with this method. 

Configuration Key
Description
autoRefreshFields
Default Value : False
A boolean configuration key to enable or disable automatic refreshing of module fields in the background. If set to true, fields are refreshed every hour, and if set to false, fields must be manually refreshed or deleted.
pickListValidation
Default Value : True
This field enables or disables pick list validation. If enabled, user input for pick list fields is validated, and if the value does not exist in the pick list, the SDK throws an error. If disabled, the input is not validated and the API call is made.
enableSSLVerification
Default Value : True
A boolean field to enable or disable curl certificate verification. If set to true, the SDK verifies the authenticity of certificate. If set to false, the SDK skips the verification.
connectionTimeout
Default Value : 0
The maximum time (in seconds) to wait while trying to connect. Use 0 to wait indefinitely.
timeout
Default Value : 0
The maximum time (in seconds) to allow cURL functions to execute. Use 0 to wait indefinitely.
  1. $autoRefreshFields = false;
  2. $pickListValidation = false;
  3. $enableSSLVerification = true;
  4. $connectionTimeout = 2;
  5. $timeout = 2;
  6. $sdkConfig = (new SDKConfigBuilder())
  7. ->autoRefreshFields($autoRefreshFields)
  8. ->pickListValidation($pickListValidation)
  9. ->sslVerification($enableSSLVerification)
  10. ->connectionTimeout($connectionTimeout)
  11. ->timeout($timeout)
  12. ->build();
g. requestProxy : Create an instance of RequestProxy containing the proxy properties of the user. Configure this only if you're using a proxy server to make the API calls.

$requestProxy = (new ProxyBuilder())
 ->host("proxyHost")
 ->port("proxyPort")
 ->user("proxyUser")
 ->password("password")
 ->build();

h. resourcePath : Configure path containing the absolute directory path to store user specific files containing module fields information.

$resourcePath = "/Documents/phpsdk-application";

5. Initilization

Once you have completed the configuration process, you can move on to initializing the SDK and begin making API requests.

Here is a sample code to initialize the SDK, using refresh token flow and DB Persistence.

<?php
use com\zoho\api\authenticator\OAuthBuilder;
use com\zoho\api\authenticator\store\DBBuilder;
use com\zoho\api\authenticator\store\FileStore;
use com\zoho\crm\api\InitializeBuilder;
use com\zoho\crm\api\UserSignature;
use com\zoho\crm\api\dc\USDataCenter;
use com\zoho\api\logger\LogBuilder;
use com\zoho\api\logger\Levels;
use com\zoho\crm\api\SDKConfigBuilder;
use com\zoho\crm\api\ProxyBuilder;
use com\zoho\api\authenticator\store\DBBuilder;

require_once "vendor/autoload.php";

class Initialize
{
  public static function initialize()
  {
    $user = new UserSignature("patricia@zoho.com");
    $environment = USDataCenter::PRODUCTION();
    $token = (new OAuthBuilder())
    ->clientId("1000.xxxxxxxxxxxxxxxx")
    ->clientSecret("554a9776d10ff016a92c1eb01xxxxxxxxxx")
    ->refreshToken("1000.xxxxxxxxxxxxxxxxxxxx")
    ->redirectURL("www.zoho.com")
    ->build();
    $logger = (new LogBuilder())
    ->level(Levels::INFO)
    ->filePath("/Documents/php_sdk_log.log")
    ->build();
   $tokenstore = (new DBBuilder())
    ->host("insert_your_hostname_here")
    ->databaseName("insert_your_database_name_here")
    ->userName("insert_your_db_username_here")
    ->password("insert_your_db_password_here")
    ->portNumber("insert_your_portnumber_here")
    ->tableName("insert_your_table_name_here")
    ->build();
    $autoRefreshFields = false;
    $pickListValidation = false;
    $connectionTimeout = 2;
    $timeout = 2;
    $sdkConfig = (new SDKConfigBuilder())
    ->autoRefreshFields($autoRefreshFields)
    ->pickListValidation($pickListValidation)
    ->sslVerification($enableSSLVerification)
    ->connectionTimeout($connectionTimeout)
    ->timeout($timeout)
    ->build();
    $resourcePath = "/Documents/phpsdk-application";
    $requestProxy = (new ProxyBuilder())
    ->host("proxyHost")
    ->port("proxyPort")
    ->user("proxyUser")
    ->password("password")
    ->build();
    (new InitializeBuilder())
    ->user($user)
    ->environment($environment)
    ->token($token)
    ->store($tokenstore)
    ->SDKConfig($configInstance)
    ->resourcePath($resourcePath)
    ->logger($logger)
    ->requestProxy($requestProxy)
    ->initialize();
  }
}
?>


You are now all set to explore the functionalities of SDK. Here is a sample code to get the records from Leads module, with the ifmodifiedsince header.

<?php
use com\zoho\api\authenticator\OAuthBuilder;
use com\zoho\crm\api\dc\USDataCenter;
use com\zoho\crm\api\InitializeBuilder;
use com\zoho\crm\api\UserSignature;
use com\zoho\crm\api\record\RecordOperations;
use com\zoho\crm\api\record\GetRecordsHeader;
use com\zoho\crm\api\HeaderMap;
use com\zoho\crm\api\ParameterMap;
require_once "vendor/autoload.php";

class Record
{
    public static function initialize()
    {
        $user = new UserSignature('myname@mydomain.com');
        $environment = USDataCenter::PRODUCTION();
        $token = (new OAuthBuilder())
        ->clientId("1000.xxxxxxx")
        ->clientSecret("4b5baxxxxxxxxxxxxf")
        ->grantToken("1000.xxxxx")
        ->build();
        (new InitializeBuilder())
            ->user($user)
            ->environment($environment)
            ->token($token)
            ->initialize();
    }

    public static function getRecords()
    {
        $recordOperations = new RecordOperations();
        $paramInstance = new ParameterMap();
        $headerInstance = new HeaderMap();
     $ifmodifiedsince = date_create("2022-06-01T12:00:00+05:30")->setTimezone(new \DateTimeZone(date_default_timezone_get()));
        $headerInstance->add(GetRecordsHeader::IfModifiedSince(), $ifmodifiedsince);
        $response = $recordOperations->getRecords("Leads", $paramInstance, $headerInstance);
        echo($response->getStatusCode() . "\n");
        print_r($response);
    }
}
Record::initialize();
Record::getRecords();


Next week, we will dive deeper and provide more sample codes to help you further. Stay tuned!

If you have any queries, let us know the comments below, or drop an email to support@zohocrm.com. We would love to hear from you. 



    • Recent Topics

    • Upload Picture to Contact

      It would be nice to upload a profile picture to a contact.
    • Allowing Pictures for Client Contacts

      Do you have any plans to allow us to add pictures of our client contacts? There is a silhouette of a person there now, but no way that I can see where I can actually add a picture of the individual.
    • Paid Support Plans with Automated Billing

      We (like many others, I'm sure) are designing or have paid support plans. Our design involves a given number of support hours in each plan. Here are my questions: 1) Are there any plans to add time-based plans in the Zoho Desk Support Plans feature? The
    • Agent name Alias

      I am seeing that Full name of my staffs are written on every ticket response which is not good for some reasons. It is possible to user like this: Manny P. (First Name with Last Name's First Letter) or  Manny (First Name) This is want we want to show
    • Unable to add attachments to tickets through Desk API

      I able to use the Desk API to generate tickets. However when I try to use the tickets/{ticketId}/attachments endpoint, I always get an Unauthorized error. My app has Desk.Tickets.ALL included in its scope so this should not be an issue
    • What's wrong with this COQL?

      What's wrong with this COQL? Code returns "invalid operator found". SELECT id, Name, Stage, Account, Created_Time, Tag FROM Production_Orders WHERE (Account = '4356038000072566002' AND Stage NOT LIKE '%customer%') ORDER BY Created_Time DESC LIMIT 200
    • [Feature Request] Add support for internationalized top-level domains mail hosting

      This is an important request to add support for internationalized domains mail hosting to https://www.zoho.com/mail/ In this case, that is only limited to domain name/mail address however currently it's already possible for us send mails etc using below
    • Add Enable/Disable to Field Rules and other Rules

      Hi, Sometimes I have rules setup for fields, and until I want to enable them for use, I can set the fields to Hidden but rules still show them, today you have to delete rules and then recreate them again, would be nice to have a toggle for Enabled/Disabled
    • Syncing stuck for days

      Hello when I made an account a few days ago and synced all my notes to it, it is still syncing. My app is only 400mb so I do not know why it is taking so long. Please help
    • Workflow runs on every edit despite not ticking the field repeat this workflow whenever a parent is edited.....

      Hi, It is my understanding that this workflow should only trigger once. Why is this triggering on every edit of the field? Based on another support query - directly from Zoho, If i tick the box 'repeat this workflow whenever a parent is edited' it should
    • How do you add or update tags on Zoho CRM records via n8n? (Workarounds or best practices?)

      Hi all, I’m running into some limitations with the Zoho CRM node in n8n and was wondering how others have handled this: From what I see, the standard Zoho CRM node in n8n doesn’t allow you to add or update tags when creating or updating contacts/leads.
    • API PARAMETER FOR TICKET CLOSED TIME

      Hi, Is there a parameter for filtering tickets by closed time in zoho api, i can see closed time in the API response i get, but can't get tickets by that field while calling. Regards, Anvin Alias
    • Reply to email addresses wrong.

      I have setup my Zoho mail account using my main domain and I also have an Alias setup from a different domain. In Settings - Mail - Compose I have selected to the option "For replies, send using The same email address to which the email was sent to".
    • Audio/video quality issues with Zoho Meeting – Any roadmap for improvement?

      Hi Zoho Team, We’ve been using Zoho Meeting for both internal and external meetings, and unfortunately, the experience has been consistently poor. The video and audio quality are so unreliable that it often renders meetings ineffective—especially with
    • Meeting integration with Otter.ai

      Would love for an integration with an AI transcription service like Otter.ai to be integrated with Zoho Meeting. Thanks
    • How to close/delete a free creator account?

      I have a free zoho creator account associated with my email address that is not being used.  I want to become a user of another paid zoho creator account but I can not associate with the paid account with the same email.  I assume if I can close or delete the free account I will be able to use the paid account. I have emailed support but no response. Suggestions?
    • Zoho books and zapier causes Invalid data provided

      I have been using zoho books with zapier for over 2 years now, everything was working fine. On September 13th my zaps stopped working. Now on step create sales invoice in zoho books i get an error: Failed to create a create_invoice_v2 in Zoho Books The
    • CRM report

      Is it possible to pull a contacts report that also includes the company industry, as well as the company name? I’m having trouble combining company and contact fields – any help is appreciated. Thank you, Sam
    • Early Payment Discount customize Text

      Hi, I’m currently using Zoho Books and am trying to customize the standard “Early Payment Discount” message that appears in the PDF invoice template. I’ve reviewed the documentation here: https://www.zoho.com/books/help/invoice/early-payment-discount.html
    • Enhancements to Client script?

      Hi Zoho CRM, I've been extensively using Client Scripts to enhance our Deal form experience, particularly for real time validations and auto updating fields based on specific logic. However, I've encountered a challenge regarding permission boundaries.
    • Add views to new CRM UI navigation + Unlimited Webtabs

      Zoho CRM is so close now to being the ultimate business application with the new UI, as soon as this one feature is added. This is probably where Zoho is headed but if it's not I want to BEG for this to be incorporated. What we need is to be able to put
    • E-Mail Distribution List

      How do I create an e-mail distribution list in Zoho Mail?
    • Custom "create meeting" button with more functionality than Zoho currently has?

      I'm looking for a little help/direction in how to do this. Even just some general high level pointers on how this might be able to be done. The current Zoho Meeting Activity functionality is not ideal for my org's workflow. I'd like to try and create
    • Error Code 4: Invalid value passed for JSONString

      Okay, I want to start by saying I know I'm a terrible scripter, so sorry if this is a dumb mistake. I just can't figure it out, even with LLM help. Here's my code: // --- Input Variables --- customer_id = salesorder.get("customer_id"); so_id = salesorder.get("salesorder_id");
    • Organizing contacts/members by company

      I work for a membership organization (representing businesses) and am trying to use Zoho CRM more effectively for managing the points of contact for our members. Currently, our members are listed in our CRM by the primary point of contact's name, but
    • Allow Stripe Credit Card and Stripe ACH payment methods to be enabled separately on an invoice.

      I need to be able to pick at the invoice level whether Stripe Credit Card and/or Stripe ACH payment methods are available. Currently, I'm not able to select from the two Stripe payment methods individually on an invoice. However, there are some larger
    • Unable to search in Zoho Email

      I've started using Zoho Email (free version) recently and realized that it doesn't have email search functionality. Am I missing anything here? I've gone through the Zoho tutorial which does show the search bar on the right top of the Zoho UI. But in
    • Response Time Report

      From data to decisions: A deep dive into ticketing system reports Every organization that interacts with its customers should have an established timeframe for how soon an agent is expected to send the first response and any reply to any follow-up messages.
    • Problem : Auto redirect from zoho flow to zoho creator

      Hi there, I've been waiting for zoho team to get back on this for last couple of days. Anyone else have the problem to access zoho flow? everytime I click on zoho flow it redirects me to zoho creator. I tried incognito mode but it still direct me to zoho
    • Zoho - Outlook plugin

      Does anyone know if there is a way to modify the autofill in the Zoho plugin in outlook? When we create a contact, it enters the correct email address and name, but then pulls information from our own signature line to add phone number, address, etc.
    • Threaded conversations for emails sent via automation

      Hi Guys, I hope you are doing well. Don't you guys think we should have an option in a workflow to notify users either as a new email or the previous email thread. For example, if you have one deal in the process and there are 10 different stages during
    • Zoho Books - Sales Person Information

      Hi Team, On Invoices, Quotes, etc... I can include the Sales Person, but it only shows their name and not their email or phone number. It would be great to have place on invoice templates where we can manage what sales person information should be shows
    • Offline working in Zoho Creator portal

      Zoho's help says that offline working is only available in the Creator mobile app and not in the portal app. But I can see offline options in the portal app too and it seems to work when I test it. My portal users are often in areas where there is poor
    • Fetch Records using Dynamic Criteria

      Hi,  I have a form that builds a filter based on user input.  I need to fetch the records based on dynamic criteria.  How would I accomplish this as there is no eval function? For example: desiredRecord = Form1[dynamicCriteria];
    • Url filter Report date (pivot chart)

      Hello. Is it possible to filter the data in pivot char using parameters in the url? I'm trying but I should not doing very well. Something like: https://creator.zoho.com/.../....../#Report:MyPivotChartReport?MyDate=01-Jan-2012;31-Jun-2012;MyDate_op=58 Saludos
    • Sending gmail to a particular person fails because the address gets changed to "gmaill", with a second "l" typo somewhere

      I send to bob@gmail.com (example) and get an error sending to bob@gmaill.com, only for this one person. Note the extra "l" in the email the system tried to send to, which was not in the address I entered. Can't find a typo in the contact or anywhere else
    • Emoji Support in Bigin CRM

      We request the implementation of emoji support across Bigin CRM. This feature should allow users to seamlessly use emojis in text fields, headlines, and deals. It would enhance communication, improve the visual appeal of records, and bring more personalization
    • Bigin Booking Pages enhancements

      I would like to ask for several enhancements for the brand new (and promising) Booking feature. 1. Add "Contact/Mobile" Field to Booking form We use Mobile as key (id), but unfortunately it is missing from the Booking form, only Home Phone is available.
    • Amount in words in Indian format

      Hi, I had coded the following code to convert amount in words. But in the code in the format of US like million. But i need in Lakh and Crore. So pls suggest ideas r post corrected code string Num2Words(int val) {     val_s = input.val.toString();     th = {"", "thousand", "million", "billion", "trillion"};     // uncomment this line for English Number System     // th = {"","thousand","million", "milliard","billion"};     dg = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
    • What are people using to send Service based emails?

      Zoho Campaigns is for marketing. Users can unsubscribe from these emails. Service based emails need to be delivered and can without the worry of Can-spam act. What are people using to send service based emails? My mailing list is derived from a database
    • Next Page