How to configure swagger with laravel passport - laravel

I'm generating rest api documentation and the tool I'm using is swagger. I've configured l5-swagger package for this. unfortunately i'm not getting the authorize option from the ui. my l5-swagger.php file
'passport' => [
'type' => 'oauth2',
'description' => 'Laravel passport oauth2 security.',
'in' => 'header',
'scheme' => 'https',
'flows' => [
"password" => [
"authorizationUrl" => config('app.url') . '/oauth/authorize',
"tokenUrl" => config('app.url') . '/oauth/token',
"refreshUrl" => config('app.url') . 'oauth/token/refresh',
"scopes" => []
],
],
],
My Controller looks like this
/**
* #OA\GET(
** path="/api/product/{product_id}",
* tags={"Product"},
* security={
* {
* "passport": {}},
* },
* summary="Product Detail",
* operationId="productdetails",
* #OA\Parameter(
* name="product_id",
* in="path",
* required=true,
* #OA\Schema(
* type="integer"
* )
* ),
* #OA\Response(
* response=200,
* description="Success",
* #OA\MediaType(
* mediaType="application/json",
* )
* ),
*)
public function get_product($product_id){
}
i'm not sure what I'm missing that's causing the disappearing of authorize lock button

Instead of writing your own security There is 'securitySchemes' => [] find passport array just uncomment that and replace the dummy oauth url with the real one's and all set.

Related

Header Auth is not send in Swagger Laravel

I am using laravel 9 and swagger and I installed the DarkaOnLine/L5-Swagger package.
In swagger config I added:
'securityDefinitions' => [
'securitySchemes' => [
'api_key_security' => [ // Unique name of security
'type' => 'apiKey', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
'description' => 'A short description for security scheme',
'name' => 'x-session-id', // The name of the header or query parameter to be used.
'in' => 'header', // The location of the API key. Valid values are "query" or "header".
],
],
'security' => [
[
'api_key_security' => []
],
],
],
and in function definition inside the controller I need to use the x-session-id header:
/**
* Create TEST
* #OA\Get (
* path="/api/test",
* tags={"test"},
* summary="Endpoint de prueba",
* security={
* {"api_key_security":{}}
* },
* #OA\RequestBody(
* #OA\MediaType(
* mediaType="application/json"
* )
* ),
* #OA\Response(
* response=200,
* description="success",
* ),
* )
*/
public function index(): ?string
I saw in internet that adding the security key it should works but when I send the request in swagger the header 'x-session-id' is not added.
You can use headers parameter in the response body like this
#OA\Header(
header="X-Rate-Limit",
description="calls per hour allowed by the user",
#OA\Schema(
type="integer",
format="int32"
)
),

Route [feeds.main] not defined with spatie/laravel-feed package

I use Laravel 8 with spatie/laravel-feed 4.0 package with this codes:
routes/web.php
Route::feeds();
config/feed.php
<?php
return [
'feeds' => [
'main' => [
/*
* Here you can specify which class and method will return
* the items that should appear in the feed. For example:
* [App\Model::class, 'getAllFeedItems']
*
* You can also pass an argument to that method. Note that their key must be the name of the parameter: *
* [App\Model::class, 'getAllFeedItems', 'parameterName' => 'argument']
*/
'items' => ['App\Models\Blog\Post', 'getFeedItems'],
/*
* The feed will be available on this url.
*/
'url' => '/feed',
'title' => 'News',
'description' => 'The description of the feed.',
'language' => 'en-US',
/*
* The image to display for the feed. For Atom feeds, this is displayed as
* a banner/logo; for RSS and JSON feeds, it's displayed as an icon.
* An empty value omits the image attribute from the feed.
*/
'image' => '',
/*
* The format of the feed. Acceptable values are 'rss', 'atom', or 'json'.
*/
'format' => 'atom',
/*
* The view that will render the feed.
*/
'view' => 'feed::atom',
/*
* The mime type to be used in the <link> tag. Set to an empty string to automatically
* determine the correct value.
*/
'type' => '',
/*
* The content type for the feed response. Set to an empty string to auatomatically
* determine the correct value.
*/
'contentType' => '',
],
],
];
app/Models/Blog/Post.php
class Post extends Model implements Feedable
{
// ...
public function toFeedItem(): FeedItem
{
return FeedItem::create([
'id' => $this->id,
'title' => $this->title,
'summary' => $this->summary,
'updated' => $this->updated_at,
'link' => $this->link,
'author' => $this->user->name,
]);
}
public static function getFeedItems()
{
return Post::orderBy('publish_date', 'desc')
->limit(10)
->get();
}
}
resources/views/layout.blade.php
<!DOCTYPE html>
<html lang="#yield('lang')">
<head>
<!-- ... -->
#include('feed::links')
</head>
<body>
<!-- ... -->
I tried to run these commands:
php artisan route:clear
php artisan optimize
...but noting changed.
I get this error message:
Route [feeds.main] not defined. (View:
/var/www/html/vendor/spatie/laravel-feed/resources/views/links.blade.php)
Any idea what I missed?
If you looking for immediate solution then you can remove
Route::feeds();
and add route like below
Route::get('feed',FeedController::class)->name("feeds.main");
and make sure name of url should match in config file
<?php
return [
'feeds' => [
'main' => [
/*
* Here you can specify which class and method will return
* the items that should appear in the feed. For example:
* [App\Model::class, 'getAllFeedItems']
*
* You can also pass an argument to that method. Note that their key must be the name of the parameter: *
* [App\Model::class, 'getAllFeedItems', 'parameterName' => 'argument']
*/
'items' => ['App\Models\Order', 'getFeedItems'],
/*
* The feed will be available on this url.
*/
'url' => '/feed',
'title' => 'My feed',
'description' => 'The description of the feed.',
'language' => 'en-US',
/*
* The image to display for the feed. For Atom feeds, this is displayed as
* a banner/logo; for RSS and JSON feeds, it's displayed as an icon.
* An empty value omits the image attribute from the feed.
*/
'image' => '',
/*
* The format of the feed. Acceptable values are 'rss', 'atom', or 'json'.
*/
'format' => 'atom',
/*
* The view that will render the feed.
*/
'view' => 'feed::atom',
/*
* The mime type to be used in the <link> tag. Set to an empty string to automatically
* determine the correct value.
*/
'type' => '',
/*
* The content type for the feed response. Set to an empty string to automatically
* determine the correct value.
*/
'contentType' => '',
],
],
];
and run following command
php artisan route:clear
php artisan optimize
Updates
Easy solution is if you specify url in config file then it wont throw error.For example in config/feed.php
'url' => '/feed',
so no need to change anythink

Laravel websocket bug

Everything is done according to your guide, re-read several times, looked at a bunch of answers on Google, but my error is not fixed! Here is a mistake:
enter image description here
enclose code:
use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize;
return [
/*
* Set a custom dashboard configuration
*/
'dashboard' => [
'port' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
],
/*
* This package comes with multi tenancy out of the box. Here you can
* configure the different apps that can use the webSockets server.
*
* Optionally you specify capacity so you can limit the maximum
* concurrent connections for a specific app.
*
* Optionally you can disable client events so clients cannot send
* messages to each other via the webSockets.
*/
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'path' => env('PUSHER_APP_PATH'),
'capacity' => null,
'enable_client_messages' => true,
'enable_statistics' => true,
],
],
/*
* This class is responsible for finding the apps. The default provider
* will use the apps defined in this config file.
*
* You can create a custom provider by implementing the
* `AppProvider` interface.
*/
'app_provider' => BeyondCode\LaravelWebSockets\Apps\ConfigAppProvider::class,
/*
* This array contains the hosts of which you want to allow incoming requests.
* Leave this empty if you want to accept requests from all hosts.
*/
'allowed_origins' => [
//
],
/*
* The maximum request size in kilobytes that is allowed for an incoming WebSocket request.
*/
'max_request_size_in_kb' => 250,
/*
* This path will be used to register the necessary routes for the package.
*/
'path' => 'laravel-websockets',
/*
* Dashboard Routes Middleware
*
* These middleware will be assigned to every dashboard route, giving you
* the chance to add your own middleware to this list or change any of
* the existing middleware. Or, you can simply stick with this list.
*/
'middleware' => [
'web',
Authorize::class,
],
'statistics' => [
/*
* This model will be used to store the statistics of the WebSocketsServer.
* The only requirement is that the model should extend
* `WebSocketsStatisticsEntry` provided by this package.
*/
'model' => \BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry::class,
/*
* Here you can specify the interval in seconds at which statistics should be logged.
*/
'interval_in_seconds' => 60,
/*
* When the clean-command is executed, all recorded statistics older than
* the number of days specified here will be deleted.
*/
'delete_statistics_older_than_days' => 60,
/*
* Use an DNS resolver to make the requests to the statistics logger
* default is to resolve everything to 127.0.0.1.
*/
'perform_dns_lookup' => false,
],
/*
* Define the optional SSL context for your WebSocket connections.
* You can see all available options at: http://php.net/manual/en/context.ssl.php
*/
'ssl' => [
/*
* Path to local certificate file on filesystem. It must be a PEM encoded file which
* contains your certificate and private key. It can optionally contain the
* certificate chain of issuers. The private key also may be contained
* in a separate file specified by local_pk.
*/
'local_cert' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT', null),
/*
* Path to local private key file on filesystem in case of separate files for
* certificate (local_cert) and private key.
*/
'local_pk' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),
/*
* Passphrase for your local_cert file.
*/
'passphrase' => env('LARAVEL_WEBSOCKETS_SSL_PASSPHRASE', null),
],
/*
* Channel Manager
* This class handles how channel persistence is handled.
* By default, persistence is stored in an array by the running webserver.
* The only requirement is that the class should implement
* `ChannelManager` interface provided by this package.
*/
'channel_manager' => \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager::class,
];
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
'host' => '127.0.0.1',
'post' => 6001,
'scheme' => 'https'
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
wsHost: window.location.hostname,
wsPort: 6001,
});
PUSHER_APP_ID=1323123
PUSHER_APP_KEY=312313123
PUSHER_APP_SECRET=312313
PUSHER_APP_CLUSTER=mt1
BROADCAST_DRIVER=pusher
APP_URL=http://smart-php.design
My site has https, maybe you need to configure it somehow? Therefore, an error occurs, before a “message” was sent to me, but after my manipulations everything again broke down.
Here is the url: http://smart-php.design
I will be extremely grateful for the support!
Thanks in advance!
You need to setup ssl certificate (refer to their document on ssl) otherwise just turn off the encryption and serve over WS.

How to make <code> work in ApiGen

Tying to generate auto doc using ApiGen.
Have add followed comment for doc generation. I was hope that block in "code" will make same appearance as in short's description, but it does not work. I'm not sure how to make the same. Are there some method?
/**
* Short desc
*
* #param array $tabs
*
* For example
* <code>
* $admin_tabs = array(
* 'AdminDeliveryManager' => array('name' => 'Delivery manager', 'id_parent' => 0),
* 'AdminRole' => array('name' => 'Admin role', 'id_parent' => -1),
* 'AdminEmployeeRole' => array('name' => 'Admin role', 'id_parent' => -1)
* );
* </code>
*
* #return boolean true if all tabs created / false if have some error
*/
ApiGen wants plain description to go first and then all the tag lines after.
Examples of how to use the function should go in an #example tag like so:
/**
* Short desc
*
* #param array $tabs
* #return boolean true if all tabs created / false if have some error
* #example
* <code>
* $admin_tabs = array(
* 'AdminDeliveryManager' => array('name' => 'Delivery manager', 'id_parent' => 0),
* 'AdminRole' => array('name' => 'Admin role', 'id_parent' => -1),
* 'AdminEmployeeRole' => array('name' => 'Admin role', 'id_parent' => -1)
* );
* createTabs($admin_tabs);
* </code>
*/

Creating Custom Options on a Product using the Magento API

How do I add custom options to a product like you can in the backend, using the API.
Im using C# but if you know how do to this in Php, that would be helpful too.
I noticed that product has this:
var product = new catalogProductCreateEntity();
product.options_container = "blah";
And there is this:
catalogAttributeOptionEntity optionEntity = new catalogAttributeOptionEntity();
optionEntity.value = "sds";
optionEntity.label = "ere";
But I cant see a way of utilizing them, im not sure how to make a container, and the catalogAttributeOptionEntity does not have all the properties needed to make a custom option.
Look at the admin product controller. Yes it is possible.
/**
* Initialize data for configurable product
*/
if (($data = $this->getRequest()->getPost('configurable_products_data')) && !$product->getConfigurableReadonly()) {
$product->setConfigurableProductsData(Zend_Json::decode($data));
}
if (($data = $this->getRequest()->getPost('configurable_attributes_data')) && !$product->getConfigurableReadonly()) {
$product->setConfigurableAttributesData(Zend_Json::decode($data));
}
$product->setCanSaveConfigurableAttributes((bool)$this->getRequest()->getPost('affect_configurable_product_attributes') && !$product->getConfigurableReadonly());
/**
* Initialize product options
*/
if (isset($productData['options']) && !$product->getOptionsReadonly()) {
$product->setProductOptions($productData['options']);
}
This is not documented anywhere (else), but at least in Magento 1.6 one can find the appropriate API methods for product options in the source code. (I don 't know since which version that feature exists.)
The API itself is defined in: app/code/core/Mage/Catalog/etc/api.xml
<catalog_product_custom_option translate="title" module="catalog">
<title>Catalog product custom options API</title>
<model>catalog/product_option_api</model>
<acl>catalog/product/option</acl>
<methods>
<add translate="title" module="catalog">
<title>Add new custom option into product</title>
<acl>catalog/product/option/add</acl>
</add>
<update translate="title" module="catalog">
<title>Update custom option of product</title>
<acl>catalog/product/option/update</acl>
</update>
<types translate="title" module="catalog">
<title>Get list of available custom option types</title>
<acl>catalog/product/option/types</acl>
</types>
<info translate="title" module="catalog">
<title>Get full information about custom option in product</title>
<acl>catalog/product/option/info</acl>
</info>
<list translate="title" module="catalog">
<title>Retrieve list of product custom options</title>
<acl>catalog/product/option/list</acl>
<method>items</method>
</list>
<remove translate="title" module="catalog">
<title>Remove custom option</title>
<acl>catalog/product/option/remove</acl>
</remove>
</methods>
</catalog_product_custom_option>
The called functions are defined in: app/code/core/Mage/Catalog/Model/Product/Option/Api.php
class Mage_Catalog_Model_Product_Option_Api extends Mage_Catalog_Model_Api_Resource
{
/**
* Add custom option to product
*
* #param string $productId
* #param array $data
* #param int|string|null $store
* #return bool $isAdded
*/
public function add( $productId, $data, $store = null )
/**
* Update product custom option data
*
* #param string $optionId
* #param array $data
* #param int|string|null $store
* #return bool
*/
public function update( $optionId, $data, $store = null )
/**
* Read list of possible custom option types from module config
*
* #return array
*/
public function types()
/**
* Get full information about custom option in product
*
* #param int|string $optionId
* #param int|string|null $store
* #return array
*/
public function info( $optionId, $store = null )
/**
* Retrieve list of product custom options
*
* #param string $productId
* #param int|string|null $store
* #return array
*/
public function items( $productId, $store = null )
/**
* Remove product custom option
*
* #param string $optionId
* #return boolean
*/
public function remove( $optionId )
/**
* Check is type in allowed set
*
* #param string $type
* #return bool
*/
protected function _isTypeAllowed( $type )
}
The $data-array also is a bit tricky, since it's keys partly depend on the selected option type. The basic $data-array looks like:
$data = array (
'is_delete' => 0,
'title' => 'Custom Option Label',
'type' => 'text',
'is_require' => 0,
'sort_order' => 1,
'additional_fields' => array (
0 => array (
'price' => '10.0000',
'price_type' => 'fixed', // 'fixed' or 'percent'
'sku' => '',
),
),
);
The additional_fields always conatin at least one row with at least the columns price, price_type and sku. More additional fields (maf: …) may be added depending on the type. The types in the group select may have more than one row specified in additional_fields. The custom option types/type-groups are:
text (maf: 'max_characters')
field
area
file (maf: 'file_extension', 'image_size_x', 'image_size_y')
file
select (maf: 'value_id', 'title', 'sort_order')
drop_down
radio
checkbox
multiple
date
date
date_time
time
Examples for complete option data arrays:
// type-group: select, type: checkbox
$data = array (
'is_delete' => 0,
'title' => 'extra Option for that product',
'type' => 'checkbox',
'is_require' => 0,
'sort_order' => 1,
'additional_fields' => array (
0 => array (
'value_id' => '3',
'title' => 'Yes',
'price' => 10.00,
'price_type' => 'fixed',
'sku' => NULL,
'sort_order' => 1,
),
1 => array (
'value_id' => 3,
'title' => 'No',
'price' => 0.00,
'price_type' => 'fixed',
'sku' => NULL,
'sort_order' => 2,
),
),
);
// type-group: text, type: field
$data = array (
'is_delete' => 0,
'title' => 'Custom Option Label',
'type' => 'text',
'is_require' => 0,
'sort_order' => 1,
'additional_fields' => array (
0 => array (
'price' => 10.00,
'price_type' => 'fixed',
'sku' => NULL,
'max_characters' => 150,
),
),
);
In the end I decided it cant be done via the API and went to the database directly.

Resources