|
Prahalad Singh  Ranawat Oodles

Prahalad Singh Ranawat (Backend-Sr. Associate Consultant L2 - Development)

Experience:5+ yrs

Prahalad Singh Ranawat is a highly skilled backend developer with extensive experience in PHP, Laravel, Magento, Headless Magento, RESTful API, Node.js, and Vue.js. He also possesses knowledge in Shopify. Prahalad has a solid background in working with Postman, Swagger, Git, MySQL, MongoDB, and the LAMP stack. With his passion for learning and creativity, he is constantly exploring new technologies to enhance his skills. He has provided DevOps support and contributed his expertise to a range of projects, including Yumi Paws, OACustomer-Dashboard, Vlad Application, Information Sharing Website, Eating Disorder Intervention, TRO Platform, and SimplyNoted.

Prahalad Singh  Ranawat Oodles
Prahalad Singh Ranawat
(Sr. Associate Consultant L2 - Development)

Prahalad Singh Ranawat is a highly skilled backend developer with extensive experience in PHP, Laravel, Magento, Headless Magento, RESTful API, Node.js, and Vue.js. He also possesses knowledge in Shopify. Prahalad has a solid background in working with Postman, Swagger, Git, MySQL, MongoDB, and the LAMP stack. With his passion for learning and creativity, he is constantly exploring new technologies to enhance his skills. He has provided DevOps support and contributed his expertise to a range of projects, including Yumi Paws, OACustomer-Dashboard, Vlad Application, Information Sharing Website, Eating Disorder Intervention, TRO Platform, and SimplyNoted.

LanguageLanguages

DotHINDI

Fluent

DotENGLISH

Conversational

Skills
Skills

DotNetflix Open Connect

60%

DotAngular/AngularJS

40%

DotTizen Application

80%

DotBootstrap

80%

DotNPM

60%

DotShopify

60%

DotChart.js

60%

DotWordpress

80%

DotCMS

60%

DotPHP

80%

DotCanvasJS

40%

DotRESTful API

60%

DotWEBFLOW

60%

DotFullstack

80%

DotHTML, CSS

100%

DotLinux

80%

DotREST/SOAP

60%

DotLEARNDASH

60%

DotTranscoding

60%

DotDRM

60%

DotMagento

80%

DotTypeScript

20%

DotLaravel

80%

DotGithub/Gitlab

80%

DotZoho

60%

DotVimeo

60%

DotEncoding

60%

DotDrupal

60%

DotVisual Studio Code

80%

DotWebOs App

80%

DotAmazon Prime Video Direct

60%

DotReactJS

40%

DotPostgres

80%

DotOBS Studio

20%

DotMySQL

80%

DotCDNs

80%

DotVue.JS

60%

DotjQuery

60%

DotJira

60%

DotAPI Testing

60%

DotNode Js

40%

DotSamsung Smart TV SDK

60%

DotJavascript

60%
ExpWork Experience / Trainings / Internship

Oct 2021-Present

Sr. Associate Consultant - Development

Gurugram, Haryana- 122011


Oodles Technologies

Gurugram, Haryana- 122011

Oct 2021-Present

May 2019-Oct 2021

Web Developer

Bangalore


Codolin Technoliges

Bangalore

May 2019-Oct 2021

Dec 2017-May 2018

Intern

Chennai


Truckjee.com

Chennai

Dec 2017-May 2018

EducationEducation

2016-2018

Dot

Vellore Institute of Technology, Vellore, Tamil Nadu

Master Of Computer Applications-COMPUTER APPLICATIONS

certificateCertifications
Dot

Certificate for Completion of Java Training

IIT Bombay, Founded by MHRD, gov of india

Issued On

Mar 2017

Dot

The Complete JavaScript Course

Udemy

Issued On

Jan 2019

Dot

'A' Certificate National Cadet Corps - NCC

NCC - India

Issued On

May 2012

Dot

Certificate of Participation Applying Statistical Methods Using R-Language

Vellore Institute of Technology

Issued On

Oct 2016

Dot

Certificate for Completion of Python Training

IIT Bombay, Founded by MHRD, gov of india

Issued On

Mar 2017

Top Blog Posts
Custom DRM Player with Dash.js for Samsung Tizen TV

Overview

Digital Rights Management (DRM) is crucial for protecting premium content in streaming applications. Samsung Tizen TV supports DRM playback using AVPlay or custom implementations with Dash.js. In this guide, we will implement a DRM-enabled player using Dash.js and integrate remote key handling for seamless navigation on a Tizen web application.

Step 1: Setting Up the Basic HTML Player Screen

First, create a player screen in player.html to display video playback.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>YourTV</title>
  <script src="../js/dash.min.js"></script>
  <link rel="stylesheet" href="player.css">
</head>
<body>
        <!-- Expire Session -->
        <!-- <div id="sessionExpirePopup" class="popup-overlay">
          <div class="popup-content">
              <p>Session expired. Please log in again.</p>
              <button id="okButton">OK</button>
          </div>
      </div> -->
             <!-- No Internet -->
             <div id="no-internet-popup">
              <img src="../images/no-wifi.png" class="no-wifi-icon" alt="no-wifi">
              <h1>No Internet Connection</h1>
              <button id="retry-button" class="retry-wifi-btn">Retry</button>
            </div>
        <!-- END No Internet -->
  <video id="videoPlayer" type="video/mp4"></video>
  <img src="../images/logo 5.png" alt="logo" class="logo-watermark">
  <div id="playPauseIcon" class="icon-container">
    <img src="../images/Icons/play-icon.png" id="playImage" alt="Play">
    <img src="../images/Icons/pause-icon.png" id="pauseImage" alt="Pause" style="display: none;">
  </div>
<script src="player.js"></script>
<script src="../js/no-internet.js"></script>
</body>
</html>

 

Step 2: Implementing DRM Playback in player.js

Next, set up Dash.js to handle DRM-protected content and remote key.

const remoteKeys = { LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, RETURN: 10009, ENTER: 13 };
let player;
let videoElement = document.querySelector("#videoPlayer");
let playPauseIcon = document.querySelector("#playPauseIcon");
let playImage = document.querySelector("#playImage");
let pauseImage = document.querySelector("#pauseImage");
let hideIconTimeout;


// Popup elements
let noInternetPopup = document.querySelector("#noInternetPopup");
let retryButton = document.querySelector("#retryButton");


(function() {
const streamUrl = localStorage.getItem("channelUrl");
const drmData = localStorage.getItem("drmData");
const widevinelicense = localStorage.getItem("widevinelicense");


console.log("streamUrl", streamUrl);
console.log("drmData", drmData);
console.log("widevinelicense", widevinelicense);


player = dashjs.MediaPlayer().create();


if (streamUrl) {
player.initialize(videoElement, streamUrl, true);


if (drmData || widevinelicense) {
player.setProtectionData({
"com.widevine.alpha": {
serverURL: "https://widevine.keyos.com/api/v4/getLicense",
httpRequestHeaders: { customdata: drmData }
},
"com.microsoft.playready": {
serverURL: "https://playready.keyos.com/api/v4/getLicense",
httpRequestHeaders: { customdata: drmData }
}
});
}
}
})();


// Function to show play/pause icon
function showPlayPauseIcon(isPlaying) {
clearTimeout(hideIconTimeout);
playPauseIcon.style.display = "block";


// Toggle between play and pause icons
if (isPlaying) {
playImage.style.display = "none";
pauseImage.style.display = "block";
} else {
playImage.style.display = "block";
pauseImage.style.display = "none";
}


// Hide the icon after 2 seconds
hideIconTimeout = setTimeout(() => {
playPauseIcon.style.display = "none";
}, 2000);
}


// Function to show no internet popup
function showNoInternetPopup() {
noInternetPopup.style.display = "block";
retryButton.focus();
}


// Function to hide no internet popup
function hideNoInternetPopup() {
noInternetPopup.style.display = "none";
}


// Remote key event handling
document.addEventListener("keydown", (event) => {
const popup = document.querySelector("#no-internet-popup");


// Check if the No Internet popup is visible
if (popup && popup.style.display === "block") {
if (event.key === 'Enter') {
retryConnection();

// Hide the popup if internet is restored
setTimeout(() => {
if (!localStorage.getItem("no_internet")) {
toggleNoInternetPopup(false);
}
}, 500);
}


// Prevent further actions if No Internet popup is visible
return;
}


// Normal key handling if internet is available
switch (event.keyCode) {
case remoteKeys.RIGHT:
console.log("Right key pressed");
break;
case remoteKeys.LEFT:
console.log("Left key pressed");
break;
case remoteKeys.DOWN:
console.log("Down key pressed");
break;
case remoteKeys.UP:
console.log("Up key pressed");
break;
case remoteKeys.ENTER:
if (videoElement.paused) {
player.play();
console.log("Video playing via Enter key");
showPlayPauseIcon(true);
} else {
player.pause();
console.log("Video paused via Enter key");
showPlayPauseIcon(false);
}
break;
case remoteKeys.RETURN:
location.href = "../programmeguide/epg.html";
break;
}
});


Step 3: Styling the Player UI (player.css)

A simple CSS for styling the player screen.

.logo-watermark {
position: absolute !important;top: 15px;left: 0;opacity: .4;width: 12%;
}
#videoPlayer{
width: 100%; height: auto;
position: relative;
}


#bufferingIcon {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #ffc800;
border-radius: 50%;
animation: spin 1s linear infinite;
z-index: 9999;
}


@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Overlay background */
.popup-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity 0.3s ease-in-out;
}

/* Popup content */
.popup-content {
background-color: rgb(0 35 96);
color: white;
padding: 60px;
border-radius: 8px;
text-align: center;
font-size: 28px;
font-weight: 900;
width: 500px;
box-shadow: 0px 4px 6px rgb(0 0 0 / 30%);
}

.popup-content button {
background-color: #ffc800;
color: #000;
border: none;
padding: 10px 20px;
font-size: 20px;
border-radius: 5px;
cursor: pointer;
margin-top: 15px;
}



/* Show popup */
.popup-overlay.show {
visibility: visible;
opacity: 1;
}
/* Centered icon container */
.icon-container {
position: absolute;
z-index: 99999;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
}
.icon-container img {
width: 80px;
height: 80px;
}

 

 

Conclusion

You now have a working DRM-enabled player using Dash.js for Samsung Tizen TV, complete with remote key navigation. For more advanced features like dynamic channel switching and UI enhancements, explore the full capabilities of Tizen's AVPlay API.

For a complete guide on building a Samsung Tizen TV EPG with remote navigation, check out this blog.

Need help with your Tizen project? Contact us to discuss your requirements!

Category: Digital Media Solutions
OBS Studio : A Versatile Open-Source Tool for Live Streaming

OBS Studio (Open Broadcaster Software) is a powerful, open-source tool for video recording and live streaming. Its flexibility and rich feature set make it a favorite among content creators, educators, and professionals. Whether you're new to live streaming or looking to enhance your workflow, this guide will walk you through configuring OBS Studio for live streaming and integrating it with AWS Lambda for advanced data handling.

In this blog, I'll also share a unique use case: how I leveraged OBS Studio to live stream ultrasound videos for parents to witness in real time, with the data securely stored on AWS Lambda.

Why Choose OBS Studio?

OBS Studio stands out due to its versatility and cost-effectiveness. Key features include:

  • Multi-Platform Support: Available on Windows, macOS, and Linux.
  • Customizable Settings: Control resolution, bitrate, and encoding to suit your needs.
  • Scene Composition: Combine multiple video and audio sources with ease.
  • Plugins and Integrations: Expand functionality with plugins.
  • Free and Open Source: No cost and customizable to your requirements.

Setting Up OBS Studio for Live Streaming

1. Installation

  1. Download OBS Studio from the official website.
  2. Run the installer and follow on-screen instructions for your operating system.

2. Initial Configuration

  1. Auto-Configuration Wizard: When you first launch OBS, it will offer to run an auto-configuration wizard. This helps optimize settings based on your hardware and streaming goals.
  2. Manual Configuration (Optional): If you're experienced, configure settings manually under Settings > Video and Settings > Output.

3. Adding Sources

Sources are the building blocks of your stream. Here's how to add common sources:

  • Video Capture Device: For webcams or external cameras.
    • Go to Sources > + > Video Capture Device.
    • Select your device and adjust settings.
  • Screen Capture: Share your screen or specific windows.
    • Go to Sources > + > Display Capture.
    • Choose the screen to capture.
  • Audio Input/Output: Add microphones or system audio.
    • Go to Sources > + > Audio Input Capture or Audio Output Capture.
  • Text and Images: Overlay text or graphics.
    • Go to Sources > + > Text (GDI+) or Image.

4. Configuring Stream Settings

  1. Navigate to Settings > Stream.
  2. Select your streaming platform (e.g., YouTube, Facebook, Twitch) or use a custom RTMP server.
  3. Enter the stream key provided by your platform.

5. Start Streaming

  • Click Start Streaming to go live. Monitor your stream in the Stats tab to ensure stable performance.

Integrating OBS Studio with WordPress

1. Setting Up WordPress for Streaming

  1. Install a Streaming Plugin: Use plugins like WP Live Streaming or Embed Plus for YouTube.
  2. Embed Streaming Code:
    • Copy the embed code or iframe from your streaming platform.
    • Paste it into your WordPress post or page.

2. Embedding OBS Streams

To use OBS with WordPress:

  1. Custom RTMP Server:
    • Use an RTMP plugin for WordPress to create a streaming endpoint.
    • Configure the RTMP settings in OBS Studio.
  2. YouTube Live or Other Platforms:
    • Stream via OBS to YouTube or other platforms.
    • Embed the live stream in your WordPress site using the platform's share/embed options.

A Unique Use Case: Streaming Ultrasound Videos

In a medical setting, I used OBS Studio to live stream ultrasound videos. This allowed parents to view their baby's ultrasound in real time, even if they were in a different location. Here's how it was done:

  1. Capturing Ultrasound Feed:
    • Connected the ultrasound machine to a video capture device.
    • Added it as a Video Capture Device source in OBS.
  2. Streaming Setup:
    • Configured OBS to stream to a private YouTube channel.
    • Embedded the stream on a secure WordPress page for parents to access.
  3. Data Storage on AWS Lambda:
    • Leveraged AWS Lambda to store streaming metadata and ultrasound snapshots.
    • Used an S3 bucket for storing video logs.

Integrating OBS Studio with AWS Lambda

AWS Lambda provides a serverless way to handle data generated during live streaming. Here's how to integrate it:

1. Setting Up AWS Lambda

  1. Create a Lambda Function:
    • Log in to AWS Management Console.
    • Go to Lambda and create a new function.
  2. Choose Runtime: Use Python, Node.js, or your preferred language.
  3. Configure Permissions:
    • Ensure the function has access to S3 and other required AWS services.

2. Using Lambda for Video Data

  1. Storing Metadata:
    • Configure OBS to send stream metadata to an API Gateway endpoint.
    • Use the endpoint to trigger the Lambda function.
  2. Saving Snapshots:
    • Capture snapshots in OBS using the hotkey feature.
    • Upload snapshots to S3, triggering a Lambda function for further processing (e.g., indexing, notifications).

3. Example Workflow

  1. OBS Stream Start:
    • OBS sends an HTTP POST request to AWS API Gateway with stream details.
    • API Gateway invokes a Lambda function to log metadata.
  2. Snapshot Upload:
    • OBS saves snapshots locally.
    • A script uploads them to S3, triggering a Lambda function for further processing (e.g., indexing, notifications).

Best Practices for Using OBS Studio

1. Optimize Performance

  • Use hardware encoding if available (e.g., NVENC for NVIDIA GPUs).
  • Close unnecessary applications to free up resources.
  • Test your internet speed to ensure adequate bandwidth.

2. Enhance Stream Quality

  • Use a bitrate suitable for your resolution (e.g., 4500 Kbps for 1080p).
  • Set keyframe interval to 2 for smooth playback.
  • Test audio levels to avoid distortion.

3. Secure Your Streams

  • Use private or unlisted settings for sensitive content.
  • Embed streams on secure platforms with authentication.

4. Regularly Update OBS

  • Stay up-to-date with the latest version to benefit from new features and security patches.

Conclusion

OBS Studio's versatility makes it an indispensable tool for live streaming. By integrating it with WordPress, you can easily share content with your audience, and AWS Lambda provides a scalable way to handle data storage and processing.

Whether you're sharing educational content, hosting events, or live streaming in unique settings like ultrasound scans, OBS Studio empowers you to deliver high-quality streams. With the steps outlined above, you're ready to configure OBS, integrate it with WordPress, and leverage AWS for a robust streaming solution.

Feel free to contact us for related projects. Our experts will reach out to you. Visit us at https://www.oodles.com/contact-us.

Category: Digital Media Solutions
Build Custom Samsung Tizen TV EPG with Remote Navigation

Creating a custom Electronic Program Guide (EPG) for Samsung Tizen TV involves dynamically populating channel and program data while ensuring smooth navigation using remote keys. This guide walks you through key aspects of building an EPG, rendering programs, and managing remote key events, making it adaptable for other TV applications.
 

Dynamic Channel and Program Rendering: Populate channels and their associated programs dynamically from an API.
Remote Key Navigation: Seamlessly navigate through the sidebar, channels, and programs using the TV remote.
Program Details Modal: Display detailed program information in a modal and handle live playback.

1. Populating Channels and Programs Dynamically
The following function fetches channel data from an API and renders channels and their programs in a grid layout:
 

function populateChannels(channels) {
   const channelContainer = document.getElementById('schedule-channels');
   const contentContainer = document.querySelector('.schedule_container_content');
   channelContainer.innerHTML = '';
   contentContainer.innerHTML = '';
   const firstSlotTime = renderTimeSlots();
   channels.forEach(channel => {
       // Create a row for the channel
       const channelRow = document.createElement('div');
       channelRow.classList.add('schedule_channel_container');
       // Add channel details
       const channelCol = document.createElement('div');
       channelCol.classList.add('schedule_channel');
       channelCol.innerHTML = `
           <div class="history_ch">
               <div class="chn-id">${channel.id}</div>
               <img loading="lazy" src="${channel.image || 'default-img.png'}" alt="${channel.callSign}" />
           </div>
       `;
       channelRow.appendChild(channelCol);
       channelContainer.appendChild(channelRow);
       // Add programs for the channel
       const programsContainer = document.createElement('div');
       programsContainer.classList.add('schedule_time_programs');
       if (channel.program && channel.program.length > 0) {
           channel.program.forEach(program => {
               const programElem = document.createElement('div');
               programElem.classList.add('schedule_time');
               const programWidth = calculateProgramWidth(program.start, program.end, firstSlotTime);
               programElem.style.width = programWidth;
               programElem.innerHTML = `
                   <h4 class="program_title">${program.title}</h4>
                   <p class="program_time">${formatTime(program.start)} - ${formatTime(program.end)}</p>
               `;
               programsContainer.appendChild(programElem);
           });
       }
       contentContainer.appendChild(programsContainer);
   });
}

2. Remote Key Navigation

Handling TV remote navigation involves managing focus states for the sidebar, channels, and programs. The code snippet below shows how to implement this:

let currentSidebarIndex = 0;
let currentChannelIndex = 0;
let currentProgramIndex = 0;
let focusedOnSidebar = true;
function focusSidebarItem(index) {
   const sidebarItems = document.querySelectorAll('.sidebar .icon');
   sidebarItems.forEach((item, i) => {
       item.classList.toggle('focus', i === index);
   });
}
function focusProgram(channelIndex, programIndex) {
   const programs = getProgramsInChannel(channelIndex);
   const programElement = programs[programIndex];
   if (programElement) {
       programElement.classList.add('focus');
       programElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
   }
}

3. Program Details Modal

When a program is focused, detailed information can be displayed in a modal:

function fetchProgramDetail(channelId, programId) {
   const apiUrl = 'https://api.example.com/program-details';
   fetch(apiUrl, {
       method: 'POST',
       headers: { 'Content-Type': 'application/json' },
       body: JSON.stringify({ channel_id: channelId, program_id: programId }),
   })
       .then(response => response.json())
       .then(data => {
           populateModal(data);
       })
       .catch(error => console.error('API Error:', error));
}
function populateModal(data) {
   document.getElementById('programTitle').textContent = data.title || 'N/A';
   document.getElementById('programDescription').textContent = data.description || 'Description not available';
}

4. Live Program Indicator

Highlighting programs currently airing is essential for an interactive EPG:

function checkIfPlayingNow(programElement) {
   const now = Date.now() / 1000;
   const startTime = parseInt(programElement.querySelector('.program_time').getAttribute('data-starttime'), 10);
   const endTime = parseInt(programElement.querySelector('.program_time').getAttribute('data-endtime'), 10);
   return startTime <= now && now <= endTime;
}

 

Steps to Implement

   Set Up API Integration: Replace the demo API with your API for fetching channels and programs.

   Render Channels and Programs: Use populateChannels() to dynamically generate the grid.

   Implement Remote Navigation: Leverage focusSidebarItem() and focusProgram() to handle remote key events.

   Add Program Details Modal: Use fetchProgramDetail() and populateModal() to display detailed program information.

   Live Indicator: Use checkIfPlayingNow() to highlight live programs.

 

Conclusion

This blog covers the essential steps to build a custom EPG for Samsung Tizen TV, focusing on dynamic data rendering and remote key navigation. By following these techniques, developers can create an interactive and user-friendly EPG tailored to their needs. Additional features like search, filtering, or DRM content playback can further enhance the application.

If you need help building your OTT or TV web app, we're here to assist. Our expertise spans custom EPG development, DRM integration, and more. Please feel free to reach out here to discuss your project!

Category: Digital Media Solutions
REST API for updating existing order item data in Magento 2

if you need to update sales_order_item table after placing an order (while your product is based on subscription method), here you will get step by step information on how to update sales order item table data using rest api.
create or add in your existing module custom rest api in magento 2.x. 
Step1 : -  create interface file in <oodles>/<ProductRE>/Api/GetCustomProductListManagementInterface.php and paste below code

<?php
declare(strict_types=1);
namespace oodles\ProductRE\Api;
interface GetCustomProductListManagementInterface
{
  /**
     * GET for update order item Data api
     * @api
     * @return mixed|null
     */
    public function updateOrderItem(); 
}

Step 2: - create file in  app/code/oodles/ProductRE/Model/GetCustomProductListManagement.php and paste below code 
 

<?php
declare(strict_types=1);
namespace oodles\ProductRE\Model;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use oodles\ProductRE\Api\GetCustomProductListManagementInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Catalog\Model\Product;
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
class GetCustomProductListManagement implements GetCustomProductListManagementInterface
{
protected $productCollectionFactory;
protected $request;
protected $product;
protected $caloriemanagemt;
protected $_orderItems;
protected $orderItemRepo;
protected $itemFactory;
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
RequestInterface $request,
Product $product,
\Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory $orderItems,
\Magento\Sales\Model\Order\ItemFactory $itemFactory,
\Magento\Sales\Api\OrderItemRepositoryInterface $orderItem
){
$this->productCollectionFactory = $productCollectionFactory;
$this->request = $request;
$this->product = $product;
$this->_orderItems = $orderItems;
$this->itemFactory = $itemFactory;
$this->orderItemRepo = $orderItem;
}
/**
* GET for update order item Data api
* @api
* @return mixed|null
*/
public function updateOrderItem(){
//Get base64 order data (name,sku,price,order id,option's data)
$orderDatas = $this->request->getParam('order_data');
//Convert base64 data into array
$ordersData = json_decode(base64_decode($orderDatas),true);
foreach($ordersData as $orderData){
$order = $this->itemFactory->create()->getCollection()->addFieldToFilter('petdata', $orderData[0]["petdata"]);
foreach ($order as $items) {
$itemId = $items->getItemId();
$order = $this->orderItemRepo->get($itemId);
$option = $items->getProductOptions();
$option['info_buyRequest']['options'] = $orderData[0]['options'];//id of option
$option['options']['value'] = $orderData[0]['value']; //name of option
$option['options']['print_value'] = $orderData[0]['print_value']; // name of option
$order->setSku($orderData[0]['sku']);//set new sku
$order->setName($orderData[0]['name']);//set new name of product
$order->setPrice($orderData[0]['price']);// set updated price
$order->setProductOption($option);//set all option values
$order->save();
}
echo "success";
}
}
}

Step 3: - create web api file in app/code/oodles/ProductRE/etc/webapi.xml and paste below code 

<?xml version="1.0" ?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/oodles-productre/updateorderitem" method="POST">
<service class="oodles\ProductRE\Api\GetCustomProductListManagementInterface" method="updateOrderItem"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>


Step 4: create di file in app/code/oodles/ProductRE/etc/di.xml and paste below code 

 

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="oodles\ProductRE\Api\GetCustomProductListManagementInterface" type="oodles\ProductRE\Model\GetCustomProductListManagement"/>
</config>

For more details, contact us at [email protected]. Our experts will get back to you.
 

How to return multiple array in a function using helper in Laravel

Step: 1 - Create a helper file (app/Helper.php) this file will call using autoload file for all controllers.
 

<?php

use App\Models\User;

use Illuminate\Support\Facades\Auth;

function merge_2_array($array1,$array2){

$result = array();

foreach($array1 as $k => $v){

$result[$k] = array_merge($array1[$k],$array2[$k]);

}

return($result);

}

 

 

Step: 2 - Call merge function in controller. 

Here we are calling array() method from the helper to merge all arrays in one variable and on the next step will render each array data separately to view.
 

public function chartAvgEmailData(){

$data_email_avg = [];

$data_recipients_avg = [];

$data_char_avg = [];

$data_email_time = [];

$data_email_cost = [];

$data_email_co2e = [];

$months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

for ($k = 1; $k <= 12; $k++) {

$data_email_avg[$k]['month'] = $months[$k - 1];

if (!empty($datacount[$k])) {

$data_email_avg[$k]['value'] = "your data variable add here";

}else {

$data_email_avg[$k]['value'] = 0;

}

}

//avg recipients

for ($k = 1; $k <= 12; $k++) {

$data_recipients_avg[$k]['month'] = $months[$k - 1];

if (!empty($datacount[$k])) {

$data_recipients_avg[$k]['value'] = $datacount[$k]['avg_recipients'];

}else {

$data_recipients_avg[$k]['value'] = 0;

}

}

//avg character

for ($k = 1; $k <= 12; $k++) {

$data_char_avg[$k]['month'] = $months[$k - 1];

if (!empty($datacount[$k])) {

$data_char_avg[$k]['value'] = "your data variable add here";

}else {

$data_char_avg[$k]['value'] = 0;

}

}

//time

for ($k = 1; $k <= 12; $k++) {

$data_email_time[$k]['month'] = $months[$k - 1];

if (!empty($datacount[$k])) {

$data_email_time[$k]['value'] = "your data variable add here";

}else {

$data_email_time[$k]['value']= 0;

}

}

//cost

for ($k = 1; $k <= 12; $k++) {

$data_email_cost[$k]['month'] = $months[$k - 1];

if (!empty($datacount[$k])) {

$data_email_cost[$k]['value'] = "your data variable add here";

}else {

$data_email_cost[$k]['value'] = 0;

}

}

//co2e

for ($k = 1; $k <= 12; $k++) {

$data_email_co2e[$k]['month'] = $months[$k - 1];

if (!empty($datacount[$k])) {

$data_email_co2e[$k]['value'] = "your data variable add here";

}else {

$data_email_co2e[$k]['value'] = 0;

}

}

$all_data_dashboard = array($data_email_avg,$data_recipients_avg,$data_char_avg,$data_email_time,$data_email_cost,$data_email_co2e);

return ($all_data_dashboard);

}

 

Step: 3 - call method that has all merged data.

 

public function dashboard(){

//call here all merge array and store in each variable to render

$all_data_dashboard = $this->chartAvgEmailData();

 

$data_dash_email_avg = $all_data_dashboard[0];

$data_dash_recipients_avg = $all_data_dashboard[1];

$data_dash_char_avg = $all_data_dashboard[2];

$data_dash_email_time = $all_data_dashboard[3];

$data_dash_email_cost = $all_data_dashboard[4];

$data_dash_email_co2e = $all_data_dashboard[5];

return view('dashboard.dashboard',compact('data_dash_email_avg','data_dash_recipients_avg','data_dash_char_avg','data_dash_email_time','data_dash_email_cost','data_dash_email_co2e'));

}

 

conclusion:  we have created a helper method to merge array data and used a method where to merge multiple array data. then we have rendered each array of data separately to send to view for each chart. This process will help you when you need to manage multiple chart data to render on a single view. 


Contact us at  [email protected] , our experts will get back to you.
 

Magento Rest APIs to fetch all country and region by country code

In Magento 2.x we can fetch all the regions and countries and also we can fetch all the regions of the specific country by passing a country code. In this article, we will create Rest APIs to fetch all regions and countries. So first of all we will create a new module or we can use a custom module to create these Rest APIs. 

Module Structure:

Oodles/YumiAPI

-Api/Countryregion

       -CountryregionInterface.php

-etc

       -di.xml

       -webapi.xml

       -module.xml

-Model/Countryregion

       -Countryregion.php

-registration.php

 

You can use the steps provided here to add a custom module for fetching country and region data using rest apis.

 

Step 1) Create registration.php

 

-Oodles/YumiAPI/registration.php

 

<?php

   \Magento\Framework\Component\ComponentRegistrar::register(

       \Magento\Framework\Component\ComponentRegistrar::MODULE,

       'Oodles_YumiAPI',

       __DIR__

   );

 

Step 2) Create module.xml file 

 

-Oodles/YumiAPI/etc/module.xml

 

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">

<module name="Oodles_YumiAPI" setup_version="0.0.1"/>

</config>

 

Step 3) Create CountryregionInterface.php file to create your method

-Oodles/YumiAPI/Api/Countryregion/CountryregionInterface.php

 

<?php

namespace Oodles\YumiAPI\Api\Countryregion;

 

interface CountryregionInterface

{

 

  /**

  * Get country options list.

  *

  * @return array

  */

   public function getAllCountry();

 

   /**

  * Returns json data after processing to Countryregion

  *

  * @api

  * @return bool json data after processing to Countryregion.

  */

 public function getAllRegion();

 

}

 

Step 4) Create Countryregion.php file to add logic and DI code.

-Oodles/YumiAPI/Model/Countryregion/Countryregion.php

 

<?php

declare(strict_types=1);

namespace Oodles\YumiAPI\Model\Countryregion;

 

use Magento\Framework\App\RequestInterface;

use Magento\Store\Model\StoreManagerInterface;

use Magento\Framework\App\ObjectManager;

use Magento\Directory\Model\Country as country;

use Magento\Directory\Model\CountryFactory;

use Magento\Directory\Model\ResourceModel\Country\CollectionFactory as CountryCollectionFactory;

use Magento\Directory\Model\ResourceModel\Region\CollectionFactory as RegionCollectionFactory;

 

use Oodles\YumiAPI\Api\Countryregion\CountryregionInterface;

 

class Countryregion implements CountryregionInterface

 

{

   protected $country;

   protected $countryFactory;

 

   protected $storeManager;

   /**

   *

   * @param StoreManagerInterface $storeManager

   */

 

   protected $request;

   /**

    *

    * @param RequestInterface $request

    */

 

   protected $countryCollectionFactory;

   /**

    *

    * @param countryCollectionFactory $countryCollectionFactory

    */

   protected $regionCollectionFactory;

   /**

    *

    * @param regionCollectionFactory $regionCollectionFactory

    */

  

   public function __construct(

       RequestInterface $request,

       CountryCollectionFactory $countryCollectionFactory,

       RegionCollectionFactory $regionCollectionFactory,

       StoreManagerInterface $storeManager = null,

       country $country,

       countryFactory $countryFactory

   ) {

       $this->request = $request;

       $this->country = $country;

       $this->countryCollectionFactory = $countryCollectionFactory;

       $this->regionCollectionFactory = $regionCollectionFactory;

       $this->storeManager = $storeManager;

       $this->countryFactory = $countryFactory;

   }

    /**

    * {@inheritdoc}

    */

   public function getAllCountry()

   {

     $collection = $this->countryCollectionFactory->create()->loadByStore();

     $counties =  $collection->getData();

     $res = array();

     $count = 0;

     foreach($counties as $country) {

       $res[$count]['country_id'] = $country['country_id'];

       $countryy = $this->countryFactory->create()->loadByCode($country['country_id']);

       $res[$count]['country'] = $countryy->getName();

       $count++;

     }

     return $res;

  }

   /**

  * Returns json data after processing to Countryregion

  *

  * @api

  * @return bool json data after processing to Countryregion.

  */

 public function getAllRegion(){

   $countryCode  = $this->request->getParam('country_id');

   $regionCollection = $this->country->loadByCode($countryCode)->getRegions();

   $regions = $regionCollection->loadData()->toOptionArray(false);

   return $regions;

 }

}


 

Step 5) Now we need to add CountryregionInterface.php into di.xml

- Oodles/YumiAPI/etc/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

   <preference for="Oodles\YumiAPI\Api\Countryregion\CountryregionInterface" type="Oodles\YumiAPI\Model\Countryregion\Countryregion" />

</config>

 

Step 6) Finally we need to add webapi.xml file to register our api

- Oodles/YumiAPI/etc/webapi.xml

 

<?xml version="1.0"?>

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

  <route url="/V1/yumimage/getallcountry" method="GET">

   <service class="Oodles\YumiAPI\Api\Countryregion\CountryregionInterface" method="getAllCountry"/>

   <resources>

   <resource ref="anonymous"/>

   </resources>

 </route>

 

 <route url="/V1/yumimage/getallregionbycid" method="GET">

   <service class="Oodles\YumiAPI\Api\Countryregion\CountryregionInterface" method="getAllRegion"/>

   <resources>

   <resource ref="anonymous"/>

   </resources>

 </route>

</routes>



 

Endpoint of APIs: GET

  1. To fetch all country - {{base_url}}/rest/V1/yumimage/getallcountry
  2. To fetch regions of the specific country by passing a country code (pass in api url country code that you will get in getallcountry api response) - {{base_url}}/rest/V1/yumimage/getallregionbycid?country_id=IN

 

get all country response: 

[

{

"country_id": "AD",

"country": "Andorra"

},

{

"country_id": "AE",

"country": "United Arab Emirates"

},

{

"country_id": "AF",

"country": "Afghanistan"

},

{

"country_id": "AG",

"country": "Antigua & Barbuda"

},

{

"country_id": "AI",

"country": "Anguilla"

},

{

"country_id": "AL",

"country": "Albania"

},

{

"country_id": "AM",

"country": "Armenia"

},

{

"country_id": "AN",

"country": null

},

{

"country_id": "AO",

"country": "Angola"

},

{

"country_id": "AQ",

"country": "Antarctica"

},

{

"country_id": "AR",

"country": "Argentina"

},

{

"country_id": "AS",

"country": "American Samoa"

},

{

"country_id": "AT",

"country": "Austria"

},

{

"country_id": "AU",

"country": "Australia"

},

{

"country_id": "AW",

"country": "Aruba"

},

{

"country_id": "AX",

"country": "Åland Islands"

},

{

"country_id": "AZ",

"country": "Azerbaijan"

},

{

"country_id": "BA",

"country": "Bosnia & Herzegovina"

},

{

"country_id": "BB",

"country": "Barbados"

},

{

"country_id": "BD",

"country": "Bangladesh"

},

{

"country_id": "BE",

"country": "Belgium"

},

{

"country_id": "BF",

"country": "Burkina Faso"

},

{

"country_id": "BG",

"country": "Bulgaria"

},

{

"country_id": "BH",

"country": "Bahrain"

},

{

"country_id": "BI",

"country": "Burundi"

},

{

"country_id": "BJ",

"country": "Benin"

}

]

 

2) get regions by country id response:  rest/V1/yumimage/getallregionbycid?country_id=IN

 

[

{

"title": "",

"value": "",

"label": "Please select a region, state or province."

},

{

"value": "533",

"title": "Andaman and Nicobar Islands",

"country_id": "IN",

"label": "Andaman and Nicobar Islands"

},

{

"value": "534",

"title": "Andhra Pradesh",

"country_id": "IN",

"label": "Andhra Pradesh"

},

{

"value": "535",

"title": "Arunachal Pradesh",

"country_id": "IN",

"label": "Arunachal Pradesh"

},

{

"value": "536",

"title": "Assam",

"country_id": "IN",

"label": "Assam"

},

{

"value": "537",

"title": "Bihar",

"country_id": "IN",

"label": "Bihar"

},

{

"value": "538",

"title": "Chandigarh",

"country_id": "IN",

"label": "Chandigarh"

},

{

"value": "539",

"title": "Chhattisgarh",

"country_id": "IN",

"label": "Chhattisgarh"

},

{

"value": "540",

"title": "Dadra and Nagar Haveli",

"country_id": "IN",

"label": "Dadra and Nagar Haveli"

},

{

"value": "541",

"title": "Daman and Diu",

"country_id": "IN",

"label": "Daman and Diu"

},

{

"value": "542",

"title": "Delhi",

"country_id": "IN",

"label": "Delhi"

},

{

"value": "543",

"title": "Goa",

"country_id": "IN",

"label": "Goa"

},

{

"value": "544",

"title": "Gujarat",

"country_id": "IN",

"label": "Gujarat"

},

{

"value": "545",

"title": "Haryana",

"country_id": "IN",

"label": "Haryana"

},

{

"value": "546",

"title": "Himachal Pradesh",

"country_id": "IN",

"label": "Himachal Pradesh"

},

{

"value": "547",

"title": "Jammu and Kashmir",

"country_id": "IN",

"label": "Jammu and Kashmir"

},

{

"value": "548",

"title": "Jharkhand",

"country_id": "IN",

"label": "Jharkhand"

},

{

"value": "549",

"title": "Karnataka",

"country_id": "IN",

"label": "Karnataka"

},

{

"value": "550",

"title": "Kerala",

"country_id": "IN",

"label": "Kerala"

},

{

"value": "551",

"title": "Lakshadweep",

"country_id": "IN",

"label": "Lakshadweep"

},

{

"value": "552",

"title": "Madhya Pradesh",

"country_id": "IN",

"label": "Madhya Pradesh"

},

{

"value": "553",

"title": "Maharashtra",

"country_id": "IN",

"label": "Maharashtra"

},

{

"value": "554",

"title": "Manipur",

"country_id": "IN",

"label": "Manipur"

},

{

"value": "555",

"title": "Meghalaya",

"country_id": "IN",

"label": "Meghalaya"

},

{

"value": "556",

"title": "Mizoram",

"country_id": "IN",

"label": "Mizoram"

},

{

"value": "557",

"title": "Nagaland",

"country_id": "IN",

"label": "Nagaland"

},

{

"value": "558",

"title": "Odisha",

"country_id": "IN",

"label": "Odisha"

},

{

"value": "559",

"title": "Puducherry",

"country_id": "IN",

"label": "Puducherry"

},

{

"value": "560",

"title": "Punjab",

"country_id": "IN",

"label": "Punjab"

},

{

"value": "561",

"title": "Rajasthan",

"country_id": "IN",

"label": "Rajasthan"

},

{

"value": "562",

"title": "Sikkim",

"country_id": "IN",

"label": "Sikkim"

},

{

"value": "563",

"title": "Tamil Nadu",

"country_id": "IN",

"label": "Tamil Nadu"

},

{

"value": "564",

"title": "Telangana",

"country_id": "IN",

"label": "Telangana"

},

{

"value": "565",

"title": "Tripura",

"country_id": "IN",

"label": "Tripura"

},

{

"value": "566",

"title": "Uttar Pradesh",

"country_id": "IN",

"label": "Uttar Pradesh"

},

{

"value": "567",

"title": "Uttarakhand",

"country_id": "IN",

"label": "Uttarakhand"

},

{

"value": "568",

"title": "West Bengal",

"country_id": "IN",

"label": "West Bengal"

}

]

 

If you are looking for eCommerce store development or Magento 2.x-based development solutions, feel free to contact us at  [email protected].Our experts will get back to you.

 

Banner

Don't just hire talent,
But build your dream team

Our experience in providing the best talents in accordance with diverse industry demands sets us apart from the rest. Hire a dedicated team of experts to build & scale your project, achieve delivery excellence, and maximize your returns. Rest assured, we will help you start and launch your project, your way – with full trust and transparency!