Phalcon ORM isNew - phalcon

Does Phalcon's ORM have something like isNew?
Currently I'm use:
{% if user.getID() %}
{{ 'Edit user ' ~ user.name }}
{% else %}
{{ 'New user' }}
{% endif %}
but not sure if this is the right way.
Phalcon 1.3.x please.
Thanks

I use this type of pattern on all my models and use isNew() in the same way you do.
class SomeModel extends Phalcon\Mvc\Collection {
public static function getNew() {
$t = new self();
$t->someFieldToInit = 'some-val';
return $t;
}
public static function findByIdOrNew($_id) {
$t = self::findById($_id);
return $t ?: self::getNew();
}
public function isNew() {
return !$this->getId();
}
}

The method getId seems not available in the last version : https://docs.phalconphp.com/3.4/en/api/Phalcon_Mvc_Model
It could use the "dirty state" instead :
public function isNew() {
return $this->getDirtyState() == self::DIRTY_STATE_TRANSIENT;
}

What isNew mean in your situation? If it checked anyone has just register into your site. Maybe we could use authentication to get that User

Related

Render aria-current attribute with blazor's NavLink component

Blazor's NavLink component detects whether the link refers to the current page, and sets the active class.
It is customary to also set the aria-current="page" attribute, when it is part of a menu.
Can the component do that somehow? Or could I wrap it in a custom component that does this?
I can't find an extension point that easily allows for this: docs, source.
Extending the existing NavLink
public class NavLinkExtended : NavLink
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "a");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "class", CssClass);
if(CssClass.Contains("active"))
{
builder.AddAttribute(3, "aria-current", "page");
builder.AddContent(4, ChildContent);
builder.CloseElement();
}
else
{
builder.AddContent(3, ChildContent);
builder.CloseElement();
}
}
}
Here is my solution.
AriaNavLink.razor:
<NavLink class=#CssClass #attributes=Attributes>
#ChildContent
</NavLink>
#inherits NavLink
#code {
private const string _defaultActiveClass = "active";
private Dictionary<string, object>? _attributes;
private IReadOnlyDictionary<string, object> Attributes
{
get
{
if (_attributes != null) return _attributes;
_attributes = AdditionalAttributes != null
? new Dictionary<string, object>(AdditionalAttributes)
: new Dictionary<string, object>();
// the trick to inferring "active" indirectly:
var isActive = CssClass?.Split(' ', StringSplitOptions.TrimEntries).Contains(ActiveClass ?? _defaultActiveClass) ?? false;
if (isActive)
_attributes.Add("aria-current", "page");
return _attributes;
}
}
}
Some page using bootstrap:
<li class="nav-item">
<AriaNavLink href="/foo" class="nav-link" foo="bar">
<i class="some-icon"></i>
Foo
</AriaNavLink>
</li>
Pardon me for not being exact, but... I would approach this with something like...
aria-current="#(route == nav route) ? "page" : "" ")
and then figure out how to detect the route of the current page and the configured nav route for the thing you're modifying.
Then, if you have a LOT of these nav things and you don't want to duplicate the logic all over the place.... write a method that does the above and add that to your code like...
The accepted answer is a good solution for now. When v8 is released (probably November 2023), the functionality will be built-in. The merged PR is here.

livewire view don't send any xhr request to component

I have a select html tag in livewire view:
<select wire:model="categoryId" wire:change="$emit('attr_cat', $event.target.value)" name="category_id" class="form-control">
<option value="0">Select category</option>
#foreach($categories as $category)
<option value="{{$category->id}}">{{ $category->name }}</option>
#if(count($category->childs))
#include('admin.categories.subcategorylist',['childs' => $category->childs])
#endif
#endforeach
</select>
and a livewire component with following code:
namespace App\Http\Livewire\Admin;
use App\Models\Attribute;
use App\Models\Category;
use App\Models\CategoryAttribute;
use Barryvdh\Debugbar\Facade as Debugbar;
use Livewire\Component;
class CategoryAttributes extends Component
{
public $attributeId;
public $categoryId;
public $attributeCategories;
public $categories;
protected $listeners = ['attr_cat' => 'addAttributeToCategory'];
public function mount()
{
$this->attributeCategories = Attribute::find($this->attributeId)->categories()->get();
$this->categories = Category::whereNull('category_id')->orderBy('name')->with('childs')->get();
$this->categoryId = 0;
}
public function render()
{
return view('livewire.admin.category-attributes');
// return view('livewire.admin.cat-attr-test');
}
public function addAttributeToCategory($value){
Debugbar::addMessage($value);
CategoryAttribute::create([
'category_id' => $this->categoryId,
'attribute_id' => $this->attributeId,
]);
}
public function updatedCategoryId(){
Debugbar::addMessage($this->attributeId);
}
}
and mount livewire component with this line in my blade view:
#livewire('admin.category-attributes', ['attributeId' => $attribute->id], key('attr-'.$attribute->id))
but, when I change selected item, nothing happens and no xhr requests are sent to the server by the browser.
Let me say this too, I have inserted #livewireStyles and #livewireScripts in master blade file and they are loaded correctly.
Thank you for your help.
I found the solution to my problem. I had to put all the contents of the view in a standalone tag so that livewire could assign an ID to it. Otherwise, livewire will refuse to send any request to the server. 

How to export PDF from back-end edit/update view using DynamicPDF plugin in OctoberCMS

I am going to use DynamicPDF plugin to export to pdf some fields from backend on update/edit view of my plugin in OctoberCMS, can someone help me?
on plugin controller i have this call:
<?php namespace Vimagem\Pacientes\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
use Renatio\DynamicPDF\Classes\PDF;
use Renatio\DynamicPDF\Classes\PDFWrapper;
class Pacientes extends Controller
{
public $implement = [ 'Backend\Behaviors\ListController', 'Backend\Behaviors\FormController', 'Backend\Behaviors\ReorderController' ];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Vimagem.Pacientes', 'main-menu-item');
}
/** PDF **/
public function pdf($id)
{
return PDF::loadTemplate('export-data-pdf')->stream('download.pdf');
}
}
On the PDF Template (export-data-pdf) i need to call some form fields from one client:
{{ name }}
{{ address }}
{{ phone }}
etc...
but i can´t get the fields show up, what its wrong ?
Thank you,
Vitor
This code was found in the plugins documents.
use Renatio\DynamicPDF\Classes\PDF; // import facade
...
public function pdf()
{
$templateCode = 'renatio::invoice'; // unique code of the template
$data = ['name' => 'John Doe']; // optional data used in template
return PDF::loadTemplate($templateCode, $data)->stream('download.pdf');
}
I have used this plugin and it works well. You need to pass in data to the PDF stream.
This is done, worked around a solution for this.
Here is the controller application:
<?php namespace Vimagem\Pacientes\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
use Renatio\DynamicPDF\Classes\PDFWrapper;
use Vimagem\Pacientes\Models\Paciente;
use \October\Rain\Database\Traits\Validation;
use Str;
class Pacientes extends Controller
{
public $implement = [ 'Backend\Behaviors\ListController', 'Backend\Behaviors\FormController', 'Backend\Behaviors\ReorderController' ];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Vimagem.Pacientes', 'main-menu-item');
}
/**** PDF Export ***/
public function pdf($id)
{
$paciente = Paciente::find($id);
if ($paciente === null) {
throw new ApplicationException('User not found.');
}
$filename = Str::slug($paciente->nome) . '.pdf';
try {
/** #var PDFWrapper $pdf */
$pdf = app('dynamicpdf');
$options = [
'logOutputFile' => storage_path('temp/log.htm'),
];
return $pdf
->loadTemplate('export-data-pdf', compact('paciente'))
->setOptions($options)
->stream($filename);
} catch (Exception $e) {
throw new ApplicationException($e->getMessage());
}
}
}
Now i can use partials on the template like this:
<p>{{ paciente.nome }}</p>
<p>{{ paciente.morada }}</p>
etc...
Thank you all that try to helped me.
Vitor

Is Sylius PayumBundle handling payment details incorrectly?

I am testing Bitbag/PayUPlugin and I was stopped by gateway API with error "Required data missing".
After some debugging, I realised that Sylius Payment entity, specifically "details" property, is not fulfilled with data.
After change condition on line 53:
https://github.com/Sylius/Sylius/blob/4e06a4dfb8dc56731470016bb97165f3025947b7/src/Sylius/Bundle/PayumBundle/Action/CapturePaymentAction.php#L53
to
if ($status->isNew() || $status->isUnknown()) {
payment gateway seems to work correctly.
Is it a bug or am I doing something wrong ?
Sylius/Sylius v1.4.6
Bitbag/PayUPlugin v1.8.0
Unlikely there is an error in PayumBundle/CapturePaymentAction (because more people used PayumBundle than PayUPlugin, so probability of bug is less), conceptually payment object status at the beginning should be "new" instead of "unknown", so the condition should work.
So you should find out https://github.com/BitBagCommerce/SyliusPayUPlugin/blob/master/src/Action/StatusAction.php#L58 class, why it doesn't reach markNew() line.
I guess the BitBagCommerce/SyliusPayUPlugin is dead as this issue hasn't been addressed yet, since July.
In order to fix this I had to decorate the StatusAction class:
<?php
declare(strict_types=1);
namespace App\Payment\PayU;
use BitBag\SyliusPayUPlugin\Action\StatusAction;
use BitBag\SyliusPayUPlugin\Bridge\OpenPayUBridgeInterface;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Request\GetStatusInterface;
final class StatusActionDecorator implements ActionInterface
{
private $action;
public function __construct(StatusAction $action)
{
$this->action = $action;
}
public function setApi($api): void
{
$this->action->setApi($api);
}
public function execute($request): void
{
/** #var $request GetStatusInterface */
RequestNotSupportedException::assertSupports($this, $request);
$model = ArrayObject::ensureArrayObject($request->getModel());
$status = $model['statusPayU'] ?? null;
if (empty($status) || OpenPayUBridgeInterface::NEW_API_STATUS === $status) {
$request->markNew();
return;
}
if (OpenPayUBridgeInterface::PENDING_API_STATUS === $status) {
$request->markPending();
return;
}
if (OpenPayUBridgeInterface::CANCELED_API_STATUS === $status) {
$request->markCanceled();
return;
}
if (OpenPayUBridgeInterface::WAITING_FOR_CONFIRMATION_PAYMENT_STATUS === $status) {
$request->markSuspended();
return;
}
if (OpenPayUBridgeInterface::COMPLETED_API_STATUS === $status) {
$request->markCaptured();
return;
}
$request->markUnknown();
}
public function supports($request): bool
{
return $this->action->supports($request);
}
}
then in the services.yaml:
App\Payment\PayU\StatusActionDecorator:
decorates: bitbag.payu_plugin.action.status
arguments: ['#App\Payment\PayU\StatusActionDecorator.inner']

laravel unable to parse data

I want to go to page edit from PayAbleIndex to PayAbleEdit.
On laravel 5.4 i could use:
<button class="btn btn-primary">Edit</button>.
But currently I'm working on laravel 5.7 and i copy same code but laravel couldn't get any data from it.
My blade.php
#foreach($purchase as $data)
<tr>
<td>{{ $data->id }}</td>
<td>{{ $data->created_at }}</td>
<td>#if($data->import == 'y')Yes #else No #endif</td>
<td>Edit {{ $data->id }}</td>
</tr>
#endforeach
my controller
public function edit(accountPayAble $accountPayAble)
{
$pa = accountPayAble::where('purchases',$accountPayAble->id)->get();
return view('pages.payAbleEdit',['pa' => $pa]);
}
My accountPayAble Primary key are not ID but purchases
my account payable model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class accountPayAble extends Model
{
protected $table = "account_pay_ables";
protected $primaryKey = 'purchases';
public $timestamps =false;
public function purchase(){
return $this->belongsTo('App\purchase','purchases');
}
}
I think controller return array name should be purchase as below
public function edit(accountPayAble $accountPayAble)
{
$pa = accountPayAble::where('purchases',$accountPayAble->id)->get();
return view('pages.payAbleEdit',['purchase' => $pa]);
}
Check this and if it is not possible comment below.
Here is how generally edit method works
If you're passing id in edit method parameter in blade like this
Edit {{ $data->id }}
In this case route must have /{id}
// If you are using resource route then it will add /{id} in your edit parameter
Route::resource('payable', 'AccountPayAble');
// If you've defined custom route then
Route::get('/payable/edit/{id}','AccountPayAble#edit')->name('payable.edit');
In Your controller
// then you need to pass as well in your Controller method
public function edit(Request $request, $id)
{
$ap = AccountPayAble::find($id);
// OR
$ap = AccountPayAble::where('primary_key',$id)->first();
return view('pages.payAbleEdit',compact('ap'));
}
// If you've primary key other than id then define key into your model
protected $primaryKey = 'your_key_name';
I hope this helps.