Sonata admin configureFormFields add action - sonata-admin

How i can add custom action to configureFormFields Admin
class ContractAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
///here
}
}
I try add action to this menu

Custom admin action you add add according to the manual. What are you writing about is form fields for add / edit action.
For the buttons, you need to override method getActionButtons
public function getActionButtons($action, $object = null)
{
$actions = parent::getActionButtons($action, $object);
if ($action == 'edit') {
$actions['myKey'] = ['template' => 'template_path_to_render.html.twig'];
}
return $actions;
}

Related

abp io AbpDataFilterOptions

i am trying to configure new data filter for IMayHaveCreator. I saw example for ISoftDelete and did the same thing.
in MyAppEntityFrameworkCoreModule ive added another configure method for Filter but it does not work
public class SimplyAirEntityFrameworkCoreModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
SimplyAirEfCoreEntityExtensionMappings.Configure();
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<SimplyAirDbContext>(options =>
{
/* Remove "includeAllEntities: true" to create
* default repositories only for aggregate roots */
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
/* The main point to change your DBMS.
* See also SimplyAirMigrationsDbContextFactory for EF Core tooling. */
options.UseNpgsql();
});
Configure<AbpDataFilterOptions>(options =>
{
options.DefaultStates[typeof(IMayHaveCreator)] = new DataFilterState(isEnabled: true);
});
}
}
am i doing something wrong
I've managed to implement it. solution was to add override for CreateFilterExpression and ShouldFilterEntity methods in dbContext for that interface

Laravel DB transaction and events

I want that If any of the products is updated we fire an event once after the transaction finish
DB::transaction(function() {
foreach($products as $product) {
$product = Product::find($product->id) ;
$product->price = 2;
$product->update();
}
});
Laravel Eloquent models allowing you to hook into the following moments
retrieved, creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored, and replicating
The above events are varies based on the laravel version.
Laravel 8.x
If you are using Laravel 8.x, then Laravel took care of eloquent events with the transaction.
You just need to use public $afterCommit = true; in your observer.
Then the eloquent event will fire after committing a transaction.
Reference: https://laravel.com/docs/8.x/eloquent#observers-and-database-transactions
Laravel < 8.x
Those who are using the below version, Please have a look at the below code.
You need to create a trait inside app/Traits folder
In app/Traits/TransactionalEloquentEvents.php
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Events\TransactionCommitted;
use Illuminate\Support\Facades\Log;
trait TransactionalEloquentEvents
{
protected static $eloquentEvents = ['created', 'updated'];
protected static $queuedTransactionalEvents = [];
public static function bootTransactionalEloquentEvents()
{
$dispatcher = static::getEventDispatcher();
if (!$dispatcher) {
return;
}
foreach (self::$eloquentEvents as $event) {
static::registerModelEvent($event, function (Model $model) use ($event) {
/*get updated parameters*/
$updatedParams = array_diff($model->getOriginal(),$model->getAttributes());
if ($model->getConnection()->transactionLevel()) {
self::$queuedTransactionalEvents[$event][] = $model;
} else {
Log::info('Event fired without transaction '.$event. json_encode($updatedParams));
/* Do your operation here*/
}
});
}
$dispatcher->listen(TransactionCommitted::class, function (TransactionCommitted $event) {
if ($event->connection->transactionLevel() > 0) {
return;
}
foreach ((self::$queuedTransactionalEvents ?? []) as $eventName => $models) {
foreach ($models as $model) {
Log::info('Event fired with transaction '.$eventName);
/* Do your operation here*/
}
}
self::$queuedTransactionalEvents = [];
});
}
}
In your model app/Models/Product.php
<?php
namespace App\Models;
use App\Traits\TransactionalEloquentEvents;
class Product extends Model
{
use TransactionalEloquentEvents;
}
Note: In case of updated eloquent event. You will get the updated parameters through the $updatedParams variable.
The above case handles both transaction and non-transaction model operations.
I am maintaining a log here for each activity. You can do your operation too.
I have just checked the Laravel source code. I think you can utilize the Illuminate\Database\Events\TransactionCommitted event, which is provided out of the box. You can simply register this event with a listener in the EventServiceProvider:
namespace App\Providers;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
TransactionCommitted::class => [
WhatYouWantToDo::class,
],
];
}

Unpublished node

List with Views published nodes in the form of a table. Add to a table with a column that will contain a link. By clicking on the link ajax request should be sent, which makes the node unpublished.
I have views, have a link, have alert-ajax. But I don't understand how I can change the status from 0 to 1 programmatically.
My code in controller -
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\RemoveCommand;
use Drupal\Core\Controller\ControllerBase;
class CustomAjaxLinkController extends ControllerBase{
public function customAjaxLinkAlert($node) {
$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$node = $query->execute();
$status = $node-> isPublished();
if ($status === TRUE) {
$node->status = 0;
$node->save();
}
$response = new AjaxResponse();
$selector = '.customAjaxLinkAlert' ;
$response->addCommand(new RemoveCommand($selector, $node));
return $response;
}
}
There is an error in it, but I cannot figure out what I am doing wrong
You can past data's via ajax in a Drupal Controller
$.ajax({
type: 'POST',
url: '/your_module/your_function',
data: {'data': data},
});
Then in your Controller
<?php
namespace Drupal\your_module\your_contoller;
use Drupal\Core\Controller\ControllerBase;
/**
* Class your_contoller.
*/
class your_contoller extends ControllerBase {
public function your_function() {
do what you want
}
}
OR
Your button is inside a form and will submit the value.

ASP.NET MVC | ActionResult not getting called when going back to previous page

I understand that the title of the question may be vague but then that's the best way I could come up with to explain my issue at hand.
I'm overriding the OnActionExecuting function to manage my session related activities and allow/ deny requests to authorized/ unauthorized users, respectively. Along with tracking of the session, I'm also using the OnActionExecuting to load user available features for the current page into a temporary class and accessing from the view using ajax call.
namespace MyApp.Controllers
{
public class TESTController : Controller
{
[SessionTimeout]
public ActionResult Index()
{
return this.View();
}
}
}
public class SessionTimeoutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
if (ctx.Session["AppUser"] == null)
{
// Redirect to the login page
// Or deny request
}
else
{
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var actionName = filterContext.ActionDescriptor.ActionName;
var methodType = ((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.ReturnType;
if (methodType == typeof(ActionResult))
{
// Load all user access rights for the current page into a temporary memory
// by using the Action and Controller name
}
}
base.OnActionExecuting(filterContext);
}
}
The above works like a charm.. But the issue is when the user clicks on the back button of the browser or hits the backspace key. In that case, the OnActionExecuting function is never called for the ActionResult and further I am unable to load the current page access rights for the user.
Thanks & Regards,
Kshitij
Adding the following to my ActionResult made the above code to work.
[SessionTimeout]
[OutputCache(Duration = 0, NoStore = true)]
public ActionResult SomeView()
{
return this.View();
}

SonataAdmin change template list for Admin Users

i am a new user in sonata admin + fosuserbunle. I need create a new template for list when user is a admin. Check and redirect in CRUD controller or in the sonata admin.
if you need admin class and change the style template, the best option is redirect in de sonata admin class. Overwrite getTemplate() method.
class YourEntityAdmin extends Admin {
public function getTemplate($name)
{
if ($this->configurationPool->getContainer()->get('security.context')->isGranted('ROLE_ADMIN'))
{
switch ($name) {
case 'list':
return 'YourBundle:Entity:list.html.twig';
default:
return parent::getTemplate($name);
}
} else {
return parent::getTemplate($name);
}
}

Resources