ম্যাজেন্টো 2 এ কাস্টম মডিউলটির জন্য পরিষেবা চুক্তি কীভাবে বাস্তবায়ন করবেন?


42

যেহেতু এই পোস্টে দেখা গেছে: অসমর্থিত সংরক্ষণ করুন এবং সারাংশ মডেল লোড পদ্ধতিsave এবং loadপদ্ধতি Magento 2 অবচিত হয় শাখা বিকাশ।

সুতরাং, ভাল অনুশীলনটি এখন সিআরইউডি সত্তাগুলির সাথে মোকাবিলা করার জন্য পরিষেবা চুক্তিগুলি বাস্তবায়ন করতে হবে।

আমার কাস্টম মডিউল সত্তাগুলির জন্য পরিষেবা চুক্তিগুলি প্রয়োগ করতে আমার ধাপে ধাপে কী প্রক্রিয়া অনুসরণ করতে হবে?

এনবি: আমি জানি যে আমার সিআরইউডি মডেলগুলিতে হাজার হাজার পদ্ধতি থাকতে পারে, আমি এখানে বর্ণিত স্পষ্ট পদ্ধতিগুলি জিজ্ঞাসা করছি: http://devdocs.magento.com/guides/v2.0/extension-dev-guide / সংরক্ষণ-চুক্তি / ডিজাইন- প্যাটার্নস এইচটিএমএল :

  • get
  • save
  • getList
  • delete
  • deleteById

উত্তর:


90

আমি @ryanF- এর দুর্দান্ত উত্তরের পাশাপাশি কিছুটা বিশদ দিতে চাই।

আমি কাস্টম সত্তাগুলির জন্য একটি সংগ্রহস্থল যুক্ত করার কারণগুলি সংক্ষিপ্ত করতে চাই, কীভাবে এটি করা যায় তার উদাহরণ দেই এবং ওয়েব এপিআইয়ের অংশ হিসাবে কীভাবে সেই সংগ্রহস্থলগুলি প্রকাশ করতে হবে তাও ব্যাখ্যা করব।

দাবি অস্বীকার: আমি কেবল তৃতীয় পক্ষের মডিউলগুলির জন্য এটি কীভাবে করা যায় তার একটি বাস্তববাদী পদ্ধতির বর্ণনা দিচ্ছি - মূল দলগুলির নিজস্ব মান রয়েছে যা তারা অনুসরণ করে (বা না)।

সাধারণভাবে, একটি সংগ্রহস্থলের উদ্দেশ্য হ'ল স্টোরেজ সম্পর্কিত যুক্তি লুকানো।
রিপোজিটরির ক্লায়েন্টের যত্ন নেওয়া উচিত নয় যে রিটার্ন করা সত্তা কোনও অ্যারেতে মেমরিতে রাখা আছে, কোনও মাইএসকিউএল ডাটাবেস থেকে রিমোট করা হয়েছে, একটি রিমোট API বা কোনও ফাইল থেকে নেওয়া হয়েছে।
আমি ধরে নিলাম যে ম্যাগেন্টো কোর দলটি এটি করেছে যাতে তারা ভবিষ্যতে ওআরএম পরিবর্তন বা প্রতিস্থাপন করতে সক্ষম হয়। ম্যাজেন্টোতে ওআরএম বর্তমানে মডেলস, রিসোর্স মডেল এবং সংগ্রহগুলি নিয়ে গঠিত।
যদি কোনও তৃতীয় পক্ষের মডিউল কেবল সংগ্রহস্থলগুলি ব্যবহার করে তবে ম্যাজেন্টো কীভাবে এবং কোথায় ডেটা সংরক্ষণ করা হবে তা পরিবর্তন করতে পারে এবং এই গভীর পরিবর্তনগুলি সত্ত্বেও মডিউলটি কাজ চালিয়ে যাবে।

সংগ্রহস্থল সাধারণত মত পদ্ধতি আছে findById(), findByName(), put()বা remove()
Magento এসব সাধারণভাবে বলা হয় getbyId(), save()এবং delete()না, এমন ভান তারা অন্য কিছু করছেন কিন্তু টি ককটেলের ডিবি অপারেশন।

ম্যাজেন্টো 2 সংগ্রহস্থল পদ্ধতিগুলি সহজেই এপিআই সংস্থান হিসাবে প্রকাশিত হতে পারে, এগুলি তৃতীয় পক্ষের সিস্টেমগুলি বা শিরোনামহীন ম্যাজেন্টো দৃষ্টান্তগুলির সাথে একীকরণের জন্য মূল্যবান করে তোলে।

"আমি কি আমার কাস্টম সত্তার জন্য একটি সংগ্রহস্থল যুক্ত করব?"

সর্বদা হিসাবে, উত্তর হয়

"এটা নির্ভর করে".

একটি দীর্ঘ গল্প সংক্ষিপ্ত করতে, আপনার সত্তাগুলি যদি অন্য মডিউল দ্বারা ব্যবহৃত হয়, তবে হ্যাঁ, আপনি সম্ভবত একটি সংগ্রহস্থল যুক্ত করতে চান।

এখানে আরও একটি বিষয় রয়েছে যা গণনাতে আসে: ম্যাজেন্টো 2 এ, রিপোজিটরিগুলি সহজেই ওয়েব এপিআই হিসাবে প্রকাশিত হতে পারে - এটি রেস্ট এবং এসওএপি - সংস্থানসমূহ।

যদি এটি আপনার কাছে তৃতীয় পক্ষের সিস্টেমের সংহতকরণের জন্য বা শিরোনামহীন ম্যাজেন্টো সেটআপের কারণে আকর্ষণীয় হয়, তবে আবার, হ্যাঁ, আপনি সম্ভবত আপনার সত্তার জন্য একটি সংগ্রহস্থল যুক্ত করতে চান।

আমি কীভাবে আমার কাস্টম সত্তার জন্য একটি সংগ্রহস্থল যুক্ত করব?

ধরে নেওয়া যাক আপনি REST API এর অংশ হিসাবে আপনার সত্তাকে প্রকাশ করতে চান। যদি এটি সত্য না হয়, আপনি ইন্টারফেসগুলি তৈরি করতে আসন্ন অংশটি এড়িয়ে যেতে পারেন এবং সরাসরি নীচে "সংগ্রহস্থল এবং ডেটা মডেল বাস্তবায়ন তৈরি করুন" এ যেতে পারেন।

সংগ্রহস্থল এবং ডেটা মডেল ইন্টারফেস তৈরি করুন

Api/Data/আপনার মডিউল মধ্যে ফোল্ডার তৈরি করুন । এটি কেবল কনভেনশন, আপনি আলাদা অবস্থান ব্যবহার করতে পারেন তবে আপনার উচিত হবে না।
সংগ্রহস্থলটি Api/ফোল্ডারে যায় । উপ- Data/ডিরেক্টরিটি পরবর্তীকালের জন্য।

ইন Api/, আপনি যে পদ্ধতিগুলি প্রকাশ করতে চান তার সাথে একটি পিএইচপি ইন্টারফেস তৈরি করুন। ম্যাজেন্টো 2 কনভেনশন অনুসারে সমস্ত ইন্টারফেসের নাম প্রত্যয়ের সাথে শেষ হয় Interface
উদাহরণস্বরূপ, কোনও Hamburgerসত্তার জন্য, আমি ইন্টারফেসটি তৈরি করব Api/HamburgerRepositoryInterface

সংগ্রহস্থল ইন্টারফেস তৈরি করুন

ম্যাজেন্টো 2 সংগ্রহস্থলগুলি মডিউলটির ডোমেন লজিকের অংশ। এর অর্থ, কোনও সংগ্রহস্থল প্রয়োগ করার জন্য কোনও নির্দিষ্ট সেট নেই।
এটি সম্পূর্ণরূপে মডিউলটির উদ্দেশ্যে নির্ভর করে।

তবে, অনুশীলনে সমস্ত সংগ্রহস্থলগুলি বেশ একই রকম। তারা CRUD কার্যকারিতা জন্য মোড়ক হয়।
সর্বাধিক পদ্ধতি আছে getById, save, deleteএবং getList
আরও কিছু থাকতে পারে, উদাহরণস্বরূপ CustomerRepositoryএর একটি পদ্ধতি রয়েছে getযা ইমেল দ্বারা গ্রাহককে ধরে নিয়ে যায়, যার getByIdমাধ্যমে সত্তা আইডি দ্বারা গ্রাহককে পুনরুদ্ধারে ব্যবহার করা হয়।

এখানে হ্যামবার্গার সত্তার জন্য একটি উদাহরণ সংগ্রহস্থল ইন্টারফেস রয়েছে:

<?php

namespace VinaiKopp\Kitchen\Api;

use Magento\Framework\Api\SearchCriteriaInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerInterface;

interface HamburgerRepositoryInterface
{
    /**
     * @param int $id
     * @return \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getById($id);

    /**
     * @param \VinaiKopp\Kitchen\Api\Data\HamburgerInterface $hamburger
     * @return \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
     */
    public function save(HamburgerInterface $hamburger);

    /**
     * @param \VinaiKopp\Kitchen\Api\Data\HamburgerInterface $hamburger
     * @return void
     */
    public function delete(HamburgerInterface $hamburger);

    /**
     * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
     * @return \VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface
     */
    public function getList(SearchCriteriaInterface $searchCriteria);

}

গুরুত্বপূর্ণ! এখানে টাইমসিনস হতে হবে!
এখানে কয়েকটি গোটাচা রয়েছে যেগুলি ভুল হয়ে থাকলে ডিবাগ করা শক্ত hard

  1. আপনি যদি এটিকে REST এপিআইতে লাগাতে চান তবে পিএইচপি 7 স্কেলার আর্গুমেন্ট প্রকার বা রিটার্নের প্রকারগুলি ব্যবহার করবেন না !
  2. সমস্ত আর্গুমেন্টের জন্য পিএইচপিডোক টিকা এবং সমস্ত পদ্ধতিতে রিটার্নের ধরণ যুক্ত করুন!
  3. পিএইচপিডোক ব্লকে পুরোপুরি যোগ্য শ্রেণীর নাম ব্যবহার করুন !

জেএসওএন বা এক্সএমএল থেকে কীভাবে ডেটা রূপান্তর করতে হয় তা নির্ধারণ করার জন্য টীকাগুলিকে ম্যাজেন্টো ফ্রেমওয়ার্ক দ্বারা পার্স করা হয়েছে। শ্রেণি আমদানি (যা useবিবৃতি) প্রয়োগ করা হয় না!

প্রতিটি পদ্ধতির কোনও যুক্তির ধরণ এবং রিটার্নের ধরণ সহ একটি টীকা থাকতে হবে। এমনকি যদি কোনও পদ্ধতিতে কোনও আর্গুমেন্ট না নেয় এবং কোনও কিছুই না ফেরায়, তবে এটিকে টীকাতে হবে:

/**
 * @return void
 */

স্কালে প্রকার ( string, int, floatএবং bool) এ ছাড়া, নির্দিষ্ট করা আর্গুমেন্ট এবং একটি ফিরতি মান হিসাবে উভয় আছে।

নোট করুন যে উপরের উদাহরণে, এমন পদ্ধতিগুলির জন্য টীকাগুলি যা প্রত্যাবর্তন করে এমন বস্তুগুলিকে ইন্টারফেস হিসাবেও নির্দিষ্ট করা হয়।
রিটার্ন টাইপ ইন্টারফেস সবই Api\Dataনেমস্পেস / ডিরেক্টরিতে থাকে।
এটিতে তারা কোনও ব্যবসায়িক যুক্তি রাখেন না তা বোঝাতে এটি হয়। এগুলি কেবল ডেটা ব্যাগ।
আমাদের এই ইন্টারফেসগুলি পরবর্তী তৈরি করতে হবে।

ডিটিও ইন্টারফেস তৈরি করুন

আমি মনে করি ম্যাজেন্টো এই ইন্টারফেসগুলিকে "ডেটা মডেল" বলে, এটি একটি নাম যা আমি পছন্দ করি না।
শ্রেণী এই ধরনের সাধারণত একটি হিসাবে পরিচিত হয় ডেটা স্থানান্তর অবজেক্ট বা DTO
এই ডিটিও ক্লাসগুলিতে কেবল তাদের সমস্ত সম্পত্তিগুলির জন্য গেটার এবং সেটটার রয়েছে।

আমি ডিজিটাল মডেলের চেয়ে ডিটিও ব্যবহার করতে পছন্দ করার কারণটি হ'ল ওআরএম ডেটা মডেলগুলি, রিসোর্স মডেলগুলি বা মডেলগুলি দেখার সাথে বিভ্রান্ত করা কম ... অনেকগুলি জিনিস ইতিমধ্যে ম্যাগেন্তোর মডেল।

সংগ্রহস্থলের ক্ষেত্রে প্রযোজ্য পিএইচপি 7 টাইপ সম্পর্কিত একই সীমাবদ্ধতা ডিটিওগুলিতেও প্রযোজ্য।
এছাড়াও, প্রতিটি পদ্ধতিতে সমস্ত আর্গুমেন্ট প্রকার এবং রিটার্নের ধরণ সহ একটি টীকা থাকতে হবে।

<?php

namespace VinaiKopp\Kitchen\Api\Data;

use Magento\Framework\Api\ExtensibleDataInterface;

interface HamburgerInterface extends ExtensibleDataInterface
{
    /**
     * @return int
     */
    public function getId();

    /**
     * @param int $id
     * @return void
     */
    public function setId($id);

    /**
     * @return string
     */
    public function getName();

    /**
     * @param string $name
     * @return void
     */
    public function setName($name);

    /**
     * @return \VinaiKopp\Kitchen\Api\Data\IngredientInterface[]
     */
    public function getIngredients();

    /**
     * @param \VinaiKopp\Kitchen\Api\Data\IngredientInterface[] $ingredients
     * @return void
     */
    public function setIngredients(array $ingredients);

    /**
     * @return string[]
     */
    public function getImageUrls();

    /**
     * @param string[] $urls
     * @return void
     */
    public function setImageUrls(array $urls);

    /**
     * @return \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface|null
     */
    public function getExtensionAttributes();

    /**
     * @param \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface $extensionAttributes
     * @return void
     */
    public function setExtensionAttributes(HamburgerExtensionInterface $extensionAttributes);
}

যদি কোনও পদ্ধতি একটি অ্যারে পুনরুদ্ধার করে বা ফেরত দেয় তবে অ্যারেতে থাকা আইটেমের ধরণটি পিএইচপিডোক টীকাতে নির্দিষ্ট করতে হবে, তারপরে একটি খোলার এবং বন্ধ স্কোয়ার বন্ধনীটি অনুসরণ করা উচিত []
এটি উভয় স্কেলারের মানগুলির (যেমন int[]) পাশাপাশি বস্তুগুলির (যেমন IngredientInterface[]) উভয়ের ক্ষেত্রে সত্য ।

নোট করুন যে আমি Api\Data\IngredientInterfaceকোনও পদ্ধতির বস্তুর অ্যারে ফিরিয়ে দেওয়ার পদ্ধতির উদাহরণ হিসাবে ব্যবহার করছি , আমি এই পোস্টে উপাদানগুলির কোডটি শক্তভাবে যুক্ত করব না।

ExtensibleDataInterface?

উপরে উদাহরণস্বরূপ HamburgerInterfaceপ্রসারিত ExtensibleDataInterface
প্রযুক্তিগতভাবে এটি কেবল তখনই প্রয়োজন যখন আপনি চান অন্য মডিউলগুলি আপনার সত্তার সাথে বৈশিষ্ট্য যুক্ত করতে সক্ষম হবে।
যদি তা হয় তবে আপনার আরও একটি গিটার / সেটার জোড়া যুক্ত করতে হবে, ডাকা কনভেনশন অনুসারে getExtensionAttributes()এবং setExtensionAttributes()

এই পদ্ধতির রিটার্ন টাইপের নামকরণ খুব গুরুত্বপূর্ণ!

ম্যাজেন্টো 2 ফ্রেমওয়ার্কটি ইন্টারফেস, বাস্তবায়ন এবং বাস্তবায়নের জন্য কারখানাটি উত্পন্ন করবে যদি আপনি তাদের ঠিক ঠিক নাম দেন। এই যান্ত্রিকগুলির বিশদটি এই পোস্টের বাইরে থাকলেও।
কেবলমাত্র জেনে রাখুন, আপনি যে জিনিসটিকে এক্সটেনসিবল করতে চান তার ইন্টারফেসটি যদি বলা হয় \VinaiKopp\Kitchen\Api\Data\HamburgerInterface, তবে এক্সটেনশন অ্যাট্রিবিউটস টাইপ করতে হবে \VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface। সুতরাং শব্দটি প্রত্যয়টির Extensionঠিক আগে, সত্তার নাম অনুসারে be Interfaceোকাতে হবে।

আপনি যদি না চান যে আপনার সত্তাটি এক্সটেনসিবল হয়, তবে ডিটিও ইন্টারফেসের জন্য অন্য কোনও ইন্টারফেস প্রসারিত করতে হবে না getExtensionAttributes()এবং setExtensionAttributes()পদ্ধতিগুলি বাদ দেওয়া যেতে পারে।

ডিটিও ইন্টারফেস সম্পর্কে আপাতত যথেষ্ট, রিপোজিটরি ইন্টারফেসে ফিরে আসার সময়।

GetList () রিটার্ন টাইপ অনুসন্ধান ফলাফল

সংগ্রহস্থল পদ্ধতিটি getListআবার অন্য ধরণের দেয়, এটি একটি SearchResultsInterfaceউদাহরণ।

পদ্ধতিটি getListঅবশ্যই নির্দিষ্ট মেলানো অবজেক্টগুলির একটি অ্যারে ফিরিয়ে দিতে পারে SearchCriteria, তবে SearchResultsউদাহরণটি ফিরিয়ে দেওয়া প্রত্যাবর্তিত মানগুলিতে কিছু দরকারী মেটা ডেটা যুক্ত করতে দেয়।

সংগ্রহস্থল getList()পদ্ধতি বাস্তবায়নে এটি কীভাবে নীচে কাজ করে তা আপনি দেখতে পারেন ।

এখানে উদাহরণ হ্যামবার্গার অনুসন্ধান ফলাফল ইন্টারফেস:

<?php

namespace VinaiKopp\Kitchen\Api\Data;

use Magento\Framework\Api\SearchResultsInterface;

interface HamburgerSearchResultInterface extends SearchResultsInterface
{
    /**
     * @return \VinaiKopp\Kitchen\Api\Data\HamburgerInterface[]
     */
    public function getItems();

    /**
     * @param \VinaiKopp\Kitchen\Api\Data\HamburgerInterface[] $items
     * @return void
     */
    public function setItems(array $items);
}

এই সমস্ত ইন্টারফেসটি হ'ল এটি দুটি পদ্ধতির getItems()এবং setItems()প্যারেন্ট ইন্টারফেসের প্রকারগুলিকে অগ্রাহ্য করে ।

ইন্টারফেস সংক্ষিপ্তসার

আমাদের এখন নিম্নলিখিত ইন্টারফেস রয়েছে:

  • \VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface
  • \VinaiKopp\Kitchen\Api\Data\HamburgerInterface
  • \VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface

সংগ্রহস্থলের কিছুই প্রসারিত, প্রসারিত , এবং প্রসারিত ।
HamburgerInterface\Magento\Framework\Api\ExtensibleDataInterface
HamburgerSearchResultInterface\Magento\Framework\Api\SearchResultsInterface

সংগ্রহস্থল এবং ডেটা মডেল বাস্তবায়ন তৈরি করুন

পরবর্তী পদক্ষেপটি তিনটি ইন্টারফেসের বাস্তবায়ন তৈরি করা।

ভান্ডার

সংক্ষেপে, সংগ্রহস্থলটি ORM ব্যবহার করে এটি কাজ করে।

getById(), save() এবং delete()পদ্ধতি বেশ সোজা এগিয়ে আছে। , একটি কন্সট্রাকটর আর্গুমেন্ট হিসাবে সংগ্রহস্থলের মধ্যে ইনজেকশনের যা নিচে একটি বিট দেখা যায় হয়।
HamburgerFactory

public function getById($id)
{
    $hamburger = $this->hamburgerFactory->create();
    $hamburger->getResource()->load($hamburger, $id);
    if (! $hamburger->getId()) {
        throw new NoSuchEntityException(__('Unable to find hamburger with ID "%1"', $id));
    }
    return $hamburger;
}

public function save(HamburgerInterface $hamburger)
{
    $hamburger->getResource()->save($hamburger);
    return $hamburger;
}

public function delete(HamburgerInterface $hamburger)
{
    $hamburger->getResource()->delete($hamburger);
}

এখন একটি সংগ্রহস্থলের সবচেয়ে আকর্ষণীয় অংশ, getList()পদ্ধতি। পদ্ধতি অনুবাদ করতে হয়েছে সংগ্রহের পদ্ধতি কল মধ্যে শর্ত।
getList()SerachCriteria

এর জটিল অংশটি ফিল্টারগুলির জন্য সঠিকভাবে ANDএবং ORশর্তাদি পাচ্ছে , বিশেষত যেহেতু সংগ্রহে শর্ত নির্ধারণের বাক্য গঠনটি EAV বা ফ্ল্যাট টেবিল সত্তার উপর নির্ভর করে আলাদা different

বেশিরভাগ ক্ষেত্রে, getList()নীচের উদাহরণে চিত্রিত হিসাবে প্রয়োগ করা যেতে পারে।

<?php

namespace VinaiKopp\Kitchen\Model;

use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Api\SortOrder;
use Magento\Framework\Exception\NoSuchEntityException;
use VinaiKopp\Kitchen\Api\Data\HamburgerInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterfaceFactory;
use VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface;
use VinaiKopp\Kitchen\Model\ResourceModel\Hamburger\CollectionFactory as HamburgerCollectionFactory;
use VinaiKopp\Kitchen\Model\ResourceModel\Hamburger\Collection;

class HamburgerRepository implements HamburgerRepositoryInterface
{
    /**
     * @var HamburgerFactory
     */
    private $hamburgerFactory;

    /**
     * @var HamburgerCollectionFactory
     */
    private $hamburgerCollectionFactory;

    /**
     * @var HamburgerSearchResultInterfaceFactory
     */
    private $searchResultFactory;

    public function __construct(
        HamburgerFactory $hamburgerFactory,
        HamburgerCollectionFactory $hamburgerCollectionFactory,
        HamburgerSearchResultInterfaceFactory $hamburgerSearchResultInterfaceFactory
    ) {
        $this->hamburgerFactory = $hamburgerFactory;
        $this->hamburgerCollectionFactory = $hamburgerCollectionFactory;
        $this->searchResultFactory = $hamburgerSearchResultInterfaceFactory;
    }

    // ... getById, save and delete methods listed above ...

    public function getList(SearchCriteriaInterface $searchCriteria)
    {
        $collection = $this->collectionFactory->create();

        $this->addFiltersToCollection($searchCriteria, $collection);
        $this->addSortOrdersToCollection($searchCriteria, $collection);
        $this->addPagingToCollection($searchCriteria, $collection);

        $collection->load();

        return $this->buildSearchResult($searchCriteria, $collection);
    }

    private function addFiltersToCollection(SearchCriteriaInterface $searchCriteria, Collection $collection)
    {
        foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
            $fields = $conditions = [];
            foreach ($filterGroup->getFilters() as $filter) {
                $fields[] = $filter->getField();
                $conditions[] = [$filter->getConditionType() => $filter->getValue()];
            }
            $collection->addFieldToFilter($fields, $conditions);
        }
    }

    private function addSortOrdersToCollection(SearchCriteriaInterface $searchCriteria, Collection $collection)
    {
        foreach ((array) $searchCriteria->getSortOrders() as $sortOrder) {
            $direction = $sortOrder->getDirection() == SortOrder::SORT_ASC ? 'asc' : 'desc';
            $collection->addOrder($sortOrder->getField(), $direction);
        }
    }

    private function addPagingToCollection(SearchCriteriaInterface $searchCriteria, Collection $collection)
    {
        $collection->setPageSize($searchCriteria->getPageSize());
        $collection->setCurPage($searchCriteria->getCurrentPage());
    }

    private function buildSearchResult(SearchCriteriaInterface $searchCriteria, Collection $collection)
    {
        $searchResults = $this->searchResultFactory->create();

        $searchResults->setSearchCriteria($searchCriteria);
        $searchResults->setItems($collection->getItems());
        $searchResults->setTotalCount($collection->getSize());

        return $searchResults;
    }
}

এর মধ্যে FilterGroupথাকা ফিল্টারগুলিকে একটি ওআর অপারেটর ব্যবহার করে একত্রিত করতে হবে ।
লজিক্যাল অ্যান্ড অপারেটর ব্যবহার করে পৃথক ফিল্টার গ্রুপগুলি একত্রিত করা হয় ।

ইসস
এই কাজটি সবচেয়ে বড় বিট ছিল। অন্যান্য ইন্টারফেস বাস্তবায়ন সহজ।

ডিটিও

ম্যাগেন্টো মূলত ডিটিওকে পৃথক শ্রেণি হিসাবে বাস্তবায়নের উদ্দেশ্যে বিকাশকারীদের সত্তা মডেল থেকে পৃথক করে intended

কোর দলের গ্রাহক মডিউল যদিও (জন্য এটা করেছে \Magento\Customer\Api\Data\CustomerInterfaceদ্বারা বাস্তবায়িত হয় \Magento\Customer\Model\Data\Customerনা \Magento\Customer\Model\Customer)।
অন্যান্য সমস্ত ক্ষেত্রে সত্তা মডেলটি ডিটিও ইন্টারফেস প্রয়োগ করে (উদাহরণস্বরূপ \Magento\Catalog\Api\Data\ProductInterfaceএটি প্রয়োগ করা হয় \Magento\Catalog\Model\Product)।

আমি সম্মেলনগুলিতে মূল দলের সদস্যদের সম্পর্কে এ সম্পর্কে জিজ্ঞাসা করেছি, তবে কী ভাল অনুশীলন হিসাবে বিবেচিত হবে তা আমি একটি পরিষ্কার সাড়া পাইনি।
আমার ধারণাটি এই সুপারিশটি পরিত্যাগ করা হয়েছে। যদিও এই সম্পর্কে একটি সরকারী বিবৃতি পেতে ভাল লাগবে।

আপাতত আমি ডিটিও ইন্টারফেস বাস্তবায়ন হিসাবে মডেলটি ব্যবহার করার ব্যবহারিক সিদ্ধান্ত নিয়েছি। আপনি যদি পৃথক ডেটা মডেল ব্যবহার করা পরিষ্কার মনে করেন তবে নির্দ্বিধায় এটি ব্যবহার করুন। উভয় পন্থা অনুশীলনে সূক্ষ্মভাবে কাজ করে।

ডিটিও ইন্টারফেসটি যদি প্রসারিত করে Magento\Framework\Api\ExtensibleDataInterfaceতবে মডেলটি প্রসারিত করতে হবে Magento\Framework\Model\AbstractExtensibleModel
আপনি যদি এক্সটেনসিবিলিটি সম্পর্কে চিন্তা না করেন তবে মডেলটি কেবল ওআরএম মডেল বেস শ্রেণিটি প্রসারিত করতে পারে Magento\Framework\Model\AbstractModel

যেহেতু উদাহরণস্বরূপ HamburgerInterfaceপ্রসারিত ExtensibleDataInterfaceহ্যামবার্গার মডেল প্রসারিত AbstractExtensibleModel, যেমন এখানে দেখা যাবে:

<?php

namespace VinaiKopp\Kitchen\Model;

use Magento\Framework\Model\AbstractExtensibleModel;
use VinaiKopp\Kitchen\Api\Data\HamburgerExtensionInterface;
use VinaiKopp\Kitchen\Api\Data\HamburgerInterface;

class Hamburger extends AbstractExtensibleModel implements HamburgerInterface
{
    const NAME = 'name';
    const INGREDIENTS = 'ingredients';
    const IMAGE_URLS = 'image_urls';

    protected function _construct()
    {
        $this->_init(ResourceModel\Hamburger::class);
    }

    public function getName()
    {
        return $this->_getData(self::NAME);
    }

    public function setName($name)
    {
        $this->setData(self::NAME, $name);
    }

    public function getIngredients()
    {
        return $this->_getData(self::INGREDIENTS);
    }

    public function setIngredients(array $ingredients)
    {
        $this->setData(self::INGREDIENTS, $ingredients);
    }

    public function getImageUrls()
    {
        $this->_getData(self::IMAGE_URLS);
    }

    public function setImageUrls(array $urls)
    {
        $this->setData(self::IMAGE_URLS, $urls);
    }

    public function getExtensionAttributes()
    {
        return $this->_getExtensionAttributes();
    }

    public function setExtensionAttributes(HamburgerExtensionInterface $extensionAttributes)
    {
        $this->_setExtensionAttributes($extensionAttributes);
    }
}

স্থির হয়ে থাকা সম্পত্তিগুলির নামগুলি এগুলিকে এক জায়গায় রাখার অনুমতি দেয়। এগুলি গেটর / সেটার জুটি এবং সেটআপ স্ক্রিপ্ট দ্বারা ব্যবহার করা যেতে পারে যা ডেটাবেস টেবিল তৈরি করে। অন্যথায় এগুলি স্থির করে নেওয়ার কোনও লাভ নেই।

অনুসন্ধান ফলাফল

SearchResultsInterfaceযেহেতু এটি একটি কাঠামো বর্গ থেকে এটা কার্যকারিতা সব উত্তরাধিকারী করতে পারেন তিন ইন্টারফেসগুলি সহজ বাস্তবায়ন হয়।

<?php

namespace VinaiKopp\Kitchen\Model;

use Magento\Framework\Api\SearchResults;
use VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface;

class HamburgerSearchResult extends SearchResults implements HamburgerSearchResultInterface
{

}

অবজেক্টম্যানেজারের পছন্দগুলি কনফিগার করুন

বাস্তবায়নগুলি সম্পূর্ণ হলেও, আমরা এখনও ইন্টারফেসগুলি অন্য শ্রেণীর নির্ভরতা হিসাবে ব্যবহার করতে পারি না, যেহেতু ম্যাজেন্টো ফ্রেমওয়ার্ক অবজেক্ট ম্যানেজার কী প্রয়োগগুলি ব্যবহার করতে পারে তা জানে না। আমাদের 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="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" type="VinaiKopp\Kitchen\Model\HamburgerRepository"/>
    <preference for="VinaiKopp\Kitchen\Api\Data\HamburgerInterface" type="VinaiKopp\Kitchen\Model\Hamburger"/>
    <preference for="VinaiKopp\Kitchen\Api\Data\HamburgerSearchResultInterface" type="VinaiKopp\Kitchen\Model\HamburgerSearchResult"/>
</config>

কীভাবে এপিআই রিসোর্স হিসাবে সংগ্রহস্থল উন্মুক্ত করা যায়?

এই অংশটি সত্যিই সহজ, এটি ইন্টারফেস তৈরির সমস্ত কাজ করে, বাস্তবায়ন এবং তাদের একসাথে ওয়্যারিংয়ের জন্য পুরষ্কার।

আমাদের কেবল একটি 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 method="GET" url="/V1/vinaikopp_hamburgers/:id">
        <service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="getById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
    <route method="GET" url="/V1/vinaikopp_hamburgers">
        <service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="anonymouns"/>
        </resources>
    </route>
    <route method="POST" url="/V1/vinaikopp_hamburgers">
        <service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="save"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
    <route method="PUT" url="/V1/vinaikopp_hamburgers">
        <service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="save"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
    <route method="DELETE" url="/V1/vinaikopp_hamburgers">
        <service class="VinaiKopp\Kitchen\Api\HamburgerRepositoryInterface" method="delete"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

নোট করুন যে এই কনফিগারেশনটি কেবলমাত্র REST এন্ডপয়েন্টস হিসাবে সংগ্রহস্থলের ব্যবহারকে সক্ষম করে না, এটি SOAP API এর অংশ হিসাবে পদ্ধতিগুলিও প্রকাশ করে oses

প্রথম উদাহরণের রুটে, <route method="GET" url="/V1/vinaikopp_hamburgers/:id">স্থানধারককে :idম্যাপ করা পদ্ধতির সাথে যুক্তির নামের সাথে মিল করতে হবে public function getById($id)
দুটি নামের সাথে মিল রাখতে হবে, উদাহরণস্বরূপ কার্যকর /V1/vinaikopp_hamburgers/:hamburgerIdহবে না, কারণ পদ্ধতির যুক্তি ভেরিয়েবলের নাম $id

এই উদাহরণের জন্য আমি অ্যাক্সেসযোগ্যতা সেট করেছি <resource ref="anonymous"/>। এর অর্থ সম্পদটি কোনও বাধা ছাড়াই প্রকাশ্যে প্রকাশিত হয়!
কোনও লগ ইন করা গ্রাহকের জন্য কোনও সংস্থান উপলব্ধ করতে, ব্যবহার করুন <resource ref="self"/>meএক্ষেত্রে রিসোর্স এন্ডপয়েন্টের ইউআরএলটিতে বিশেষ শব্দটি $idবর্তমানে লগ ইন করা গ্রাহকের আইডি সহ একটি আর্গুমেন্ট ভেরিয়েবল পপ করতে ব্যবহৃত হবে ।
ম্যাজেন্টো গ্রাহক etc/webapi.xmlএবং আপনার CustomerRepositoryInterfaceযদি এটির প্রয়োজন হয় তা একবার দেখুন।

শেষ অবধি, <resources>প্রশাসক ব্যবহারকারীর অ্যাকাউন্টে কোনও সংস্থান ব্যবহারের সীমাবদ্ধ করতেও এটি ব্যবহার করা যেতে পারে। এটি করতে <resource>একটি etc/acl.xmlফাইলের মধ্যে সংজ্ঞায়িত একটি সনাক্তকারী রেফ সেট করুন।
উদাহরণস্বরূপ, <resource ref="Magento_Customer::manage"/>গ্রাহকদের পরিচালনা করার অধিকার প্রাপ্ত কোনও প্রশাসক অ্যাকাউন্টে অ্যাক্সেস সীমাবদ্ধ করবে।

কার্ল ব্যবহার করে একটি উদাহরণ এপিআই ক্যোয়ারী এটির মতো দেখতে পেল:

$ curl -X GET http://example.com/rest/V1/vinaikopp_hamburgers/123

Note: এই একটি উত্তর হিসাবে শুরু লিখিত https://github.com/astorm/pestle/issues/195
পরীক্ষা করে দেখুন মুষল , কিনতে Commercebug এবং পরিণত patreon @alanstorm এর


1
এই দুর্দান্ত উত্তরের জন্য ধন্যবাদ। দুঃখিত, আমি কিছু মিস করছি, তবে কোনও সত্তার জন্য পরিষ্কার ইন্টারফেস থাকার কী আছে যখন শেষে এটি অ্যাবস্ট্রাকমোডেল থেকে সেটডেটা পদ্ধতি রয়েছে যার অর্থ হল আপনি ইন্টারফেস নির্বিশেষে অবজেক্টটিতে কিছু যুক্ত করতে পারবেন?
এলডুসান

একটি শ্রেণি যে কোনও সংখ্যক ইন্টারফেস প্রয়োগ করতে পারে এবং অতিরিক্ত পদ্ধতিও যুক্ত করতে পারে। গুরুত্বপূর্ণ বিষয়টি হ'ল অন্য যে কোনও শ্রেণি কেবল ইন্টারফেসের পদ্ধতির উপর নির্ভর করে এবং এইভাবে অন্যগুলির কোনওটি সম্পর্কে সে জানে না। এটি নন-ইন্টারফেস পদ্ধতির প্রয়োগের বিশদ তৈরি করে, যে কোনও সময়ে বাহ্যিক শ্রেণিগুলি না ভেঙে পরিবর্তন করা যেতে পারে। নির্ভরতা বিপর্যয়ের পিছনে এটিই ধারণা That ক্লাস এবং যেকোন ক্লায়েন্ট উভয়ই ইন্টারফেসের উপর নির্ভর করে এবং প্রয়োগের বিবরণ সম্পর্কে জানেন না। এটা কি স্পষ্ট করে?
বিনাই

উত্তরের জন্য ধন্যবাদ, আমি আপনার অর্থ বলতে চাই। জিনিসটি হ'ল সেটডেটা একটি সর্বজনীন পদ্ধতি তাই এটি বাস্তবায়নের বিশদ হিসাবে বিবেচনা করা যায় কিনা তা আমি নিশ্চিত নই। যদি এটি জনসাধারণের পদ্ধতির মতো ব্যবহার করা বোঝায় তবে কীভাবে আমরা নিশ্চিত হতে পারি যে পরিবর্তিত হওয়ার পরে এটি বাহ্যিক কিছু ভাঙবে না?
এলডুসান

3
আমি ক্ষমা প্রার্থনা করছি. আপনি যা বর্ণনা করছেন তা সাধারণ দৃষ্টিভঙ্গি। নির্ভরতার যান্ত্রিকতা স্বজ্ঞাত নয় এবং যেহেতু পিএইচপি এই পদ্ধতিগুলিকে কল করার অনুমতি দেয় যা ইন্টারফেসের উপর নির্ভরশীল অংশ নয়, এবং যেহেতু এটি সংকলনের প্রয়োজন হয় না, এটি নির্ভরতা আরও বেশি ঝাপসা এবং পরিষ্কারভাবে দেখা শক্ত করে তোলে । এটি ম্যাজেন্টো 2 কোর-এও লক্ষ্য করা যায়, যেখানে এমন অনেকগুলি জায়গা রয়েছে যেখানে বাস্তবায়ন পদ্ধতি বলা হয় যা ইন্টারফেসের উপর নির্ভরশীল অংশ নয়। এগুলি খারাপ উদাহরণ হিসাবে পরিবেশন করে এবং পরিষ্কার এবং সুস্পষ্ট বোঝাপড়া পাওয়া আরও শক্ত করে তোলে।
বিনাই


35

@ রাফেল ডিজিটাল পিয়ানোজমে:

নিম্নলিখিত নমুনা মডিউল কাঠামো দেখুন:

app/
   code/
  |    Namespace/
  |   |    Custom/
  |   |   |    Api/
  |   |   |   |    CustomRepositoryInterface.php
  |   |   |   |    Data/
  |   |   |   |   |    CustomInterface.php
  |   |   |   |   |    CustomSearchResultsInterface.php
  |   |   |    etc/
  |   |   |   |    di.xml
  |   |   |   |    module.xml
  |   |   |    Model/
  |   |   |   |    Custom.php
  |   |   |   |    CustomRepository.php
  |   |   |   |    ResourceModel/
  |   |   |   |   |    Custom.php
  1. সংগ্রহস্থল ইন্টারফেস (পরিষেবা চুক্তি) তৈরি করুন
    Namespace/Custom/Api/CustomRepositoryInterface.php: http://codepad.org/WognSKnH

  2. অনুসন্ধানের ফলাফলগুলি অন্তর্ভুক্ত করুন
    Namespace/Custom/Api/Data/CustomSearchResultsInterface.php: http://codepad.org/zcbi8X4Z

  3. কাস্টমআইন্টারফেস (ডেটা ধারক) তৈরি করুন
    Namespace/Custom/Api/Data/CustomInterface.php: http://codepad.org/Ze53eT4o

  4. কাস্টমরোপোসিটরি (কংক্রিট রিপোজিটরি) তৈরি করুন
    Namespace/Custom/Model/CustomRepository.php: http://codepad.org/KNt5QAGZ
    এখানেই "যাদু" ঘটে। কনস্ট্রাক্টর ডিআই-এর মাধ্যমে, আপনি আপনার কাস্টম মডিউলটির জন্য সংস্থান কারখানাতে সংগ্রহ করুন; আপনার কাস্টমরোপোসিটারি ইন্টারফেসের কারণে এই সংগ্রহস্থলে CRUD সংরক্ষণের পদ্ধতি সম্পর্কে আপনাকে কাস্টমআইন্টারফেসের একটি প্যারামিটারে পাস করতে হবে । আপনার মডিউলের di.xML এর সত্তা মডেলের সাথে এই ধরণের ইন্টারফেস প্রতিস্থাপনের পছন্দ রয়েছে। সত্তা মডেলটি রিসোর্স মডেলে পাস হয়ে যায় এবং সেভ হয়।

  5. এতে অগ্রাধিকার সেট করুন
    Namespace/Custom/etc/di.xml: http://codepad.org/KmcoOUeV

  6. কাস্টম ইন্টারফেস (ডেটা ধারক) প্রয়োগকারী সত্তা মডেল
    Namespace/Custom/Model/Custom.php: http://codepad.org/xQiBU7p7

  7. সংস্থান মডেল
    Namespace/Custom/Model/ResourceModel/Custom.php: http://codepad.org/IOsxm9qW q

কয়েকটি বিষয় লক্ষণীয়:

  • দাবি পরিত্যাগী !!! আমি ইত্যাদি আপনার কাস্টম বিক্রেতার নাম স্থানে, সংস্থা নাম, মধ্যে "নামস্থান" ব্যাবহার করে ... যাই হোক না কেন আপনি যে নামটি গ্রুপ আপনার মডিউল একসঙ্গে ... "নামস্থান" এর প্রকৃত ব্যবহারের জন্য ব্যবহার সম্পূর্ণরূপে হয় না বৈধ পিএইচপি ... তাই জানি আমি সুবিধার্থে এটি করেছি এবং আমার মনে হয় না এটি কার্যকর হবে, না আমি কোনও উপায়ে এটি প্রস্তাব করি না।

  • @ রায়ান স্ট্রিট আমাকে এটি শিখিয়েছে ... তাই আমি সমস্ত কৃতিত্ব নিতে চাই না

  • আপনার প্রয়োজন অনুসারে স্পষ্টতই সংগ্রহস্থলের প্রয়োগ পরিবর্তন করুন

  • আপনি আপনার কাস্টম সত্তা মডেলগুলি / সংস্থানসমূহের মডেলগুলি / কংক্রিটের সংগ্রহস্থলে সংগ্রহের সাথে ইন্টারঅ্যাকশনটি প্রয়োগ করেন ...

  • আমি জানি যে আপনি আপনার প্রশ্নে তালিকাভুক্ত সমস্ত পদ্ধতিগুলিকে আমি সম্বোধন করিনি, তবে এটি একটি দুর্দান্ত সূচনা এবং ডক্স এবং প্রকৃত বাস্তবায়নের মধ্যকার ব্যবধানটি পূরণ করতে হবে।


রায়ান, পরিষেবা চুক্তিতে উল্লিখিত পদ্ধতিগুলি কি আমরা তৈরি কোনও কাস্টম সাবান এপিআইয়ের জন্য বাধ্যতামূলক, যেমন (সংরক্ষণ করুন), মুছে ফেলুন () ইত্যাদি?
সুশীবম 8'16

আপনি দয়া করে আমাকে ম্যাজেন্টো 2 তে কাস্টম সাবান এপিআই কীভাবে তৈরি করবেন তা সম্পর্কে একটি ধারণা দিতে পারেন?
সুশীবম 8'16

@ সাচিনস দুর্ভাগ্যক্রমে, এসওএপি সম্পর্কিত আমার কাছে কোনও অন্তর্দৃষ্টি নেই। আমি এখনও এটি খতিয়ে দেখিনি, না আমি এখনও এটি প্রয়োগ করে নি। আমি যে পরামর্শ দিতে পারি সবচেয়ে ভাল তা হল এখানে একটি নতুন প্রশ্ন খোলার। আমি বলব ডক্সগুলিও পরীক্ষা করে দেখুন, তবে দুঃখের বিষয় এটি সর্বদা সেরা কর্মের পাঠ্যক্রম নয় (তাদের অভাব হতে পারে)। আপনি সবসময় কোর কোডবেস বা তৃতীয় পক্ষের এক্সটেনশানটি একবার দেখে নিতে পারেন এবং সেখানে কোনও অন্তর্দৃষ্টি আছে কিনা তা দেখুন। শুভকামনা! যদি আপনি নিজের উত্তরটি খুঁজে পান তবে লিঙ্কটি এখানে যুক্ত করা ভাল। ধন্যবাদ
ryanF

জবাবের জন্য ধন্যবাদ, আরিএন, যাইহোক আমি আরআরএসটি ব্যবহার করে আমার মডিউলটি প্রয়োগ করেছি, যেহেতু এসওএপি এর তুলনায় এর হালকা ওজন ... আমি যদি
এসওএপিতে

3
@ryanF এই খুব দরকারী উত্তরের জন্য ধন্যবাদ। আমি জানি এটির কার্য কোডটি অনুলিপি / পেস্ট করার কথা নয় তবে অনুসরণকারীদের সুবিধার্থে এখানে কয়েকটি টাইপস রয়েছে। সংগ্রহস্থলে, কাস্টম অনুসন্ধানের ফলাফলগুলি ইন্টারফেসফ্যাক্টরিটি কাস্টম অনুসন্ধানের ফলাফলগুলি হতে হবে। $ অনুসন্ধানের ফলাফল-> সেটক্রিটরিয়া হওয়া উচিত $ অনুসন্ধানের ফলাফল-> সেট অনুসন্ধান ক্রিটরিয়া। Ach পূর্ববর্তী কাস্টমস [] শুল্ক [] হতে হবে। আমি মনে করি এটি সম্পর্কে।
টেটরঞ্জ

3

পরিষেবা চুক্তি ব্যবহারের ফাইলগুলি সম্পূর্ণ করুন

কাস্টম / মডিউল / registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Custom_Module',
    __DIR__
);

../etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Custom_Module" setup_version="1.0.0" />
</config>

../Setup/InstallSchema.php

<?php
namespace Custom\Module\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;
class InstallSchema implements InstallSchemaInterface {
    public function install( SchemaSetupInterface $setup, ModuleContextInterface $context ) {
        $installer = $setup;
        $installer->startSetup();
        $table = $installer->getConnection()->newTable(
            $installer->getTable( 'ad_shipping_quote' )
        )->addColumn(
            'entity_id',
            Table::TYPE_SMALLINT,
            null,
            [ 'identity' => true, 'nullable' => false, 'primary' => true ],
            'Post ID'
        )->addColumn(
            'product_id',
            Table::TYPE_SMALLINT,
            255,
            [ ],
            'Post ID'
        )
            ->addColumn(
            'customer_name',
            Table::TYPE_TEXT,
            255,
            [ 'nullable' => false ],
            'Post Title'
        )

            ->addColumn(
            'customer_email',
            Table::TYPE_TEXT,
            '2M',
            [ ],
            'Post Content'
        ) ->addColumn(
                'customer_comments',
                Table::TYPE_TEXT,
                255,
                [ 'nullable' => false ],
                'Post Title'
            )->addColumn(
                'date_added',
                Table::TYPE_TEXT,
                255,
                [ 'nullable' => false ],
                'Post Title'
            )->addColumn(
                'date_updated',
                Table::TYPE_TEXT,
                255,
                [ 'nullable' => false ],
                'Post Title'
            )
            ->setComment(
            'Ad Shipping Quote Table'
        );
        $installer->getConnection()->createTable( $table );
        $installer->endSetup();
    }
}

../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="Custom\Module\Api\ModelRepositoryInterface"
                type="Custom\Module\Model\ModelRepository" />
    <preference for="Custom\Module\Api\Data\ModelInterface"
                type="Custom\Module\Model\Model" />
    <preference for="Custom\Module\Api\Data\ModelSearchResultsInterface"
                type="Custom\Module\Model\ModelSearchResults" />
</config>

../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 method="GET" url="/V1/model/:id">
        <service class="Custom\Module\Api\ModelRepositoryInterface" method="getById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>


    <route method="GET" url="/V1/model">
        <service class="Custom\Module\Api\ModelRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

../Api/ModelRepositoryInterface.php

  <?php
namespace Custom\Module\Api;

use \Custom\Module\Api\Data\ModelInterface;
use \Magento\Framework\Api\SearchCriteriaInterface;

interface ModelRepositoryInterface
{
    /**
     * @api
     * @param \Custom\Module\Api\Data\ModelInterface $model
     * @return \Custom\Module\Api\Data\ModelInterface
     */
    public function save(ModelInterface $model);

    /**
     * @api
     * @param \Custom\Module\Api\Data\ModelInterface $model
     * @return \Custom\Module\Api\Data\ModelInterface
     */
    public function delete(ModelInterface $model);

    /**
     * @api
     * @param \Custom\Module\Api\Data\ModelInterface $id
     * @return void
     */
    public function deleteById($id);

    /**
     * @api
     * @param int $id
     * @return \Custom\Module\Api\Data\ModelInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getById($id);

    /**
     * @api
     * @param \Magento\Framework\Api\SearchCriteriaInterface $criteria
     * @return \Custom\Module\Api\Data\ModelSearchResultsInterface
     */
    public function getList(SearchCriteriaInterface $criteria);
}

../Api/Data/ModelInterface.php

<?php
namespace Custom\Module\Api\Data;

interface ModelInterface
{
    /**
     * Return the Entity ID
     *
     * @return int
     */
    public function getEntityId();

    /**
     * Set Entity ID
     *
     * @param int $id
     * @return $this
     */
    public function setEntityId($id);

    /**
     * Return the Product ID associated with Quote
     *
     * @return int
     */
    public function getProductId();

    /**
     * Set the Product ID associated with Quote
     *
     * @param int $productId
     * @return $this
     */
    public function setProductId($productId);

    /**
     * Return the Customer Name
     *
     * @return string
     */
    public function getCustomerName();

    /**
     * Set the Customer Name
     *
     * @param string $customerName
     * @return $this
     */
    public function setCustomerName($customerName);

    /**
     * Return the Customer Email
     *
     * @return string
     */
    public function getCustomerEmail();

    /**
     * Set the Customer Email
     *
     * @param string $customerEmail
     * @return $this
     */
    public function setCustomerEmail($customerEmail);

    /**
     * Return the Customer Comments
     *
     * @return string
     */
    public function getCustomerComments();

    /**
     * Set the Customer Comments
     *
     * @param string $customerComments
     * @return $this
     */
    public function setCustomerComments($customerComments);

    /**
     * Return the Date and Time of record added
     *
     * @return string
     */
    public function getDateAdded();

    /**
     * Set the Date and Time of record added
     *
     * @param string $date
     * @return $this
     */
    public function setDateAdded($date);

    /**
     * Return the Date and Time of record updated
     *
     * @return string
     */
    public function getDateUpdated();

    /**
     * Set the Date and Time of record updated
     *
     * @param string $date
     * @return $this
     */
    public function setDateUpdated($date);
}

..Api / ডেটা / ModelSearchResultsInterface.php

<?php

namespace Custom\Module\Api\Data;

use Magento\Framework\Api\SearchResultsInterface;

interface ModelSearchResultsInterface extends SearchResultsInterface
{
    /**
     * @return \Custom\Module\Api\Data\ModelInterface[]
     */
    public function getItems();

    /**
     * @param \Custom\Module\Api\Data\ModelInterface[] $items
     * @return $this
     */
    public function setItems(array $items);
}

../Model/Model.php

    <?php

namespace Custom\Module\Model;

use Custom\Module\Api\Data\ModelInterface;

class Model extends \Magento\Framework\Model\AbstractModel implements
    \Custom\Module\Api\Data\ModelInterface
{
    protected function _construct()
    {
        $this->_init('Custom\Module\Model\ResourceModel\Model');
    }

    /**
     * @inheritdoc
     */
    public function getEntityId()
    {
        return $this->_getData('entity_id');
    }

    /**
     * @inheritdoc
     */
    public function setEntityId($id)
    {
        $this->setData('entity_id', $id);
    }

    /**
     * @inheritdoc
     */
    public function getProductId()
    {
        return $this->_getData('product_id');
    }

    /**
     * @inheritdoc
     */
    public function setProductId($productId)
    {
        $this->setData('product_id', $productId);
    }

    /**
     * @inheritdoc
     */
    public function getCustomerName()
    {
        return $this->_getData('customer_name');
    }

    /**
     * @inheritdoc
     */
    public function setCustomerName($customerName)
    {
        $this->setData('customer_name', $customerName);
    }

    /**
     * @inheritdoc
     */
    public function getCustomerEmail()
    {
        return $this->_getData('customer_email');
    }

    /**
     * @inheritdoc
     */
    public function setCustomerEmail($customerEmail)
    {
        $this->setData('customer_email', $customerEmail);
    }

    /**
     * @inheritdoc
     */
    public function getCustomerComments()
    {
        return $this->_getData('customer_comments');
    }

    /**
     * @inheritdoc
     */
    public function setCustomerComments($customerComments)
    {
        $this->setData('customer_comments', $customerComments);
    }

    /**
     * @inheritdoc
     */
    public function getDateAdded()
    {
        return $this->_getData('date_added');
    }

    /**
     * @inheritdoc
     */
    public function setDateAdded($date)
    {
        $this->setData('date_added', $date);
    }

    /**
     * @inheritdoc
     */
    public function getDateUpdated()
    {
        return $this->_getData('date_updated');
    }

    /**
     * @inheritdoc
     */
    public function setDateUpdated($date)
    {
        $this->setData('date_updated', $date);
    }
}

../Model/ResourceModel/Model.php

<?php

namespace Custom\Module\Model\ResourceModel;

class Model extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    protected $_idFieldName = 'entity_id';

    protected function _construct()
    {
        $this->_init('ad_shipping_quote','entity_id');
    }
}

../Model/ResourceModel/Model/Collection.php

<?php

namespace Custom\Module\Model\ResourceModel\Model;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    protected $_idFieldName = 'entity_id';
    protected $_eventPrefix = 'ad_shipping_quote_collection';
    protected $_eventObject = 'quote_collection';

    protected function _construct()
    {
        $this->_init('Custom\Module\Model\Model', 'Custom\Module\Model\ResourceModel\Model');
    }
}

../Model/ModelRepository.php

 <?php
    namespace Custom\Module\Model;

    use \Custom\Module\Api\Data\ModelInterface;
    use \Custom\Module\Model\ResourceModel\Model as ObjectResourceModel;
    use \Magento\Framework\Api\SearchCriteriaInterface;
    use \Magento\Framework\Exception\CouldNotSaveException;
    use \Magento\Framework\Exception\NoSuchEntityException;
    use \Magento\Framework\Exception\CouldNotDeleteException;

    class ModelRepository implements \Custom\Module\Api\ModelRepositoryInterface
    {
        protected $objectFactory;

        protected $objectResourceModel;

        protected $collectionFactory;

        protected $searchResultsFactory;

        public function __construct(
            \Custom\Module\Model\ModelFactory $objectFactory,
            ObjectResourceModel $objectResourceModel,
            \Custom\Module\Model\ResourceModel\Model\CollectionFactory $collectionFactory,
            \Magento\Framework\Api\SearchResultsInterfaceFactory $searchResultsFactory
        ) {
            $this->objectFactory        = $objectFactory;
            $this->objectResourceModel  = $objectResourceModel;
            $this->collectionFactory    = $collectionFactory;
            $this->searchResultsFactory = $searchResultsFactory;
        }

        public function save(ModelInterface $object)
        {
            $name = $object->getCustomerName();
            $hasSpouse = $object->getSpouse();
            if ($hasSpouse == true) {
                $name = "Mrs. " . $name;
            } else {
                $name = "Miss. " . $name;
            }
            $object->setCustomerName($name);
            try {
                $this->objectResourceModel->save($object);
            } catch (\Exception $e) {
                throw new CouldNotSaveException(__($e->getMessage()));
            }
            return $object;
        }

        /**
         * @inheritdoc
         */
        public function getById($id)
        {
            $object = $this->objectFactory->create();
            $this->objectResourceModel->load($object, $id);
            if (!$object->getId()) {
                throw new NoSuchEntityException(__('Object with id "%1" does not exist.', $id));
            }
            return $object;
        }

        public function delete(ModelInterface $object)
        {
            try {
                $this->objectResourceModel->delete($object);
            } catch (\Exception $exception) {
                throw new CouldNotDeleteException(__($exception->getMessage()));
            }
            return true;
        }

        public function deleteById($id)
        {
            return $this->delete($this->getById($id));
        }

        /**
         * @inheritdoc
         */
        public function getList(SearchCriteriaInterface $criteria)
        {
            $searchResults = $this->searchResultsFactory->create();
            $searchResults->setSearchCriteria($criteria);
            $collection = $this->collectionFactory->create();
            foreach ($criteria->getFilterGroups() as $filterGroup) {
                $fields = [];
                $conditions = [];
                foreach ($filterGroup->getFilters() as $filter) {
                    $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
                    $fields[] = $filter->getField();
                    $conditions[] = [$condition => $filter->getValue()];
                }
                if ($fields) {
                    $collection->addFieldToFilter($fields, $conditions);
                }
            }
            $searchResults->setTotalCount($collection->getSize());
            $sortOrders = $criteria->getSortOrders();
            if ($sortOrders) {
                /** @var SortOrder $sortOrder */
                foreach ($sortOrders as $sortOrder) {
                    $collection->addOrder(
                        $sortOrder->getField(),
                        ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                    );
                }
            }
            $collection->setCurPage($criteria->getCurrentPage());
            $collection->setPageSize($criteria->getPageSize());
            $objects = [];
            foreach ($collection as $objectModel) {
                $objects[] = $objectModel;
            }
            $searchResults->setItems($objects);
            return $searchResults;
        }
    }

../Model/ModelSearchResults.php

namespace Custom\Module\Model;

use \Magento\Framework\Api\SearchResults;
use \Custom\Module\Api\Data\ModelSearchResultsInterface;


class ModelSearchResults extends SearchResults implements ModelSearchResultsInterface
{

}

../Controller/Index/Save.php

<?php

namespace Custom\Module\Controller\Index;

use \Magento\Framework\Controller\Result\RawFactory;

class Save extends \Magento\Framework\App\Action\Action
{

    /**
     * Index resultPageFactory
     * @var PageFactory
     */
    private $resultPageFactory;
    /**
     * @var
     */
    private $modelFactory;
    /**
     * @var
     */
    private $modelRepository;


    /**
     * Index constructor.
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Custom\Module\Model\ModelFactory $modelFactory
     * @param \Custom\Module\Model\ModelRepository $modelRepository
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Custom\Module\Model\ModelFactory $modelFactory,
        \Custom\Module\Model\ModelRepository $modelRepository
) {
        $this->resultPageFactory = $resultPageFactory;
        $this->modelFactory = $modelFactory;
        $this->modelRepository = $modelRepository;
        return parent::__construct($context);


    }

    /**
     * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        $data = [

            "product_id" => 201,
            "customer_name" => "Katrina",
            "customer_email" => "karina@kapoor.com",
            "spouse" => 1
        ];

        $obj = $this->modelFactory->create();
        $this->modelRepository->save($obj->addData($data)); // Service Contract


        //$obj->addData($data)->save(); // Model / Resource Model

        $this->resultFactory->create("raw");
    }
}

../Controller/Index/Getlist.php

<?php

namespace Custom\Module\Controller\Index;

use \Magento\Framework\Controller\Result\RawFactory;

class Getlist extends \Magento\Framework\App\Action\Action
{

    /**
     * Index resultPageFactory
     * @var PageFactory
     */
    private $resultPageFactory;
    /**
     * @var
     */
    private $modelFactory;
    /**
     * @var
     */
    private $modelRepository;
    /**
     * @var
     */
    private $searchCriteriaBuilder;


    /**
     * Index constructor.
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Custom\Module\Model\ModelRepository $modelRepository
     * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Custom\Module\Model\ModelRepository $modelRepository,
        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
) {
        $this->resultPageFactory = $resultPageFactory;
        $this->modelRepository = $modelRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        return parent::__construct($context);
    }

    /**
     * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        $_filter = $this->searchCriteriaBuilder
            ->addFilter("customer_name", "%na%", "like")->create();
        $list = $this->modelRepository->getList($_filter);
        $results = $list->getItems();
        foreach ($results as $result) {
            echo $result->getCustomerName() . "<br>";
        }




        $this->resultFactory->create("raw");
    }
}

../Controller/Index/Getbyid.php

<?php

namespace Custom\Module\Controller\Index;

use \Magento\Framework\Controller\Result\RawFactory;

class Getbyid extends \Magento\Framework\App\Action\Action
{

    /**
     * Index resultPageFactory
     * @var PageFactory
     */
    private $resultPageFactory;
    /**
     * @var
     */
    private $modelRepository;

    /**
     * Index constructor.
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Custom\Module\Model\ModelRepository $modelRepository
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Custom\Module\Model\ModelRepository $modelRepository

) {
        $this->resultPageFactory = $resultPageFactory;
        $this->modelRepository = $modelRepository;
        return parent::__construct($context);
    }

    public function execute()
    {

        $search = $this->modelRepository->getById(1);
        print_r($search->getData());

        $this->resultFactory->create("raw");
    }
}

../Controller/Index/Deletebyid.php

<?php

namespace Custom\Module\Controller\Index;

use \Magento\Framework\Controller\Result\RawFactory;

class Deletbyid extends \Magento\Framework\App\Action\Action
{

    /**
     * Index resultPageFactory
     * @var PageFactory
     */
    private $resultPageFactory;
    /**
     * @var
     */
    private $modelRepository;

    /**
     * Index constructor.
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Custom\Module\Model\ModelRepository $modelRepository
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Custom\Module\Model\ModelRepository $modelRepository

) {
        $this->resultPageFactory = $resultPageFactory;
        $this->modelRepository = $modelRepository;
        return parent::__construct($context);
    }

    public function execute()
    {

        $this->modelRepository->deleteById(1);

        $this->resultFactory->create("raw");
    }
}

../Controller/Index/Del.php

<?php

namespace Custom\Module\Controller\Index;

use \Magento\Framework\Controller\Result\RawFactory;

class Del extends \Magento\Framework\App\Action\Action
{

    /**
     * Index resultPageFactory
     * @var PageFactory
     */
    private $resultPageFactory;
    /**
     * @var
     */
    private $modelRepository;

    /**
     * Index constructor.
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Custom\Module\Model\ModelFactory $modelFactory
     * @param \Custom\Module\Model\ModelRepository $modelRepository
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Custom\Module\Model\ModelFactory $modelFactory,
        \Custom\Module\Model\ModelRepository $modelRepository

) {
        $this->resultPageFactory = $resultPageFactory;
        $this->modelFactory = $modelFactory;
        $this->modelRepository = $modelRepository;
        return parent::__construct($context);
    }

    public function execute()
    {
        $obj = $this->modelFactory->create()->load(2);
         $this->modelRepository->delete($obj);

        $this->resultFactory->create("raw");
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.