I use silverstripe 4.0.3
I made and extension for a Form. I adde the extension via yml to PageController. This is my Extension Class:
class NewsLetterFormExtension extends DataExtension
{
private static $allowed_actions = [
'NewsletterForm'
];
public function NewsletterForm()
{
$form = Form::create(
null,
__Function__,
FieldList::create(
LiteralField::create('Newsletter','<h2>NewsLetter</h2>')
->addExtraClass(''),
LiteralField::create('NLContent','<p>Erfaharen sie regelmäßig was uns beschäftigt</p>')
->addExtraClass(''),
TextField::create('FirstName')
->setAttribute('palceholder', 'Vorname')
->addExtraClass(''),
TextField::create('Surname')
->setAttribute('palceholder', 'Nachname')
->addExtraClass(''),
EmailField::create('Email')
->setAttribute('palceholder', 'E-mail Adresse')
->addExtraClass('')
),
FieldList::create(
FormAction::create('handleNewsletter', 'Senden')
->addExtraClass('btn btn-primary btn-sm')
),
RequiredFields::create('FirstName','Surname', 'Email')
);
return $form;
}
public function handleNewsletter($data, $form)
{
$Newsletter = Newsletter::create();
$form->saveInto($Newsletter);
try {
$Newsletter->write();
} catch (\Exception $e) {
return $e->getMessage();
}
$form->sessionMessage('Danke für die Newsletter Anmeldung', 'good');
return $this->redirectBack();
}
}
As Controller i am passing null. What would be the correct controller to submit it into the extension? Or is it even possible to do so?
I tried to pass it PageController and handle submission there. But I can not get it to work.
An actually i'd would like to submit into it self so that i can add it to multible page types.
You could try extending the Form class. This isn't tested but should work :)
NewsletterForm.php
class NewsletterForm extends Form {
function __construct($controller, $name) {
$form_name = $name;
$fields = FieldList::create(
LiteralField::create('Newsletter','<h2>NewsLetter</h2>')
->addExtraClass(''),
LiteralField::create('NLContent','<p>Erfaharen sie regelmäßig was uns beschäftigt</p>')
->addExtraClass(''),
TextField::create('FirstName')
->setAttribute('palceholder', 'Vorname')
->addExtraClass(''),
TextField::create('Surname')
->setAttribute('palceholder', 'Nachname')
->addExtraClass(''),
EmailField::create('Email')
->setAttribute('palceholder', 'E-mail Adresse')
->addExtraClass('')
);
$actions = FieldList::create(
FormAction::create('handleNewsletter', 'Senden')
->addExtraClass('btn btn-primary btn-sm')
);
$validator = RequiredFields::create('FirstName','Surname', 'Email')
parent::__construct($controller, $form_name, $fields, $actions, $validator);
}
handleNewsletter($data, $form) {
$Newsletter = Newsletter::create();
$form->saveInto($Newsletter);
try {
$Newsletter->write();
} catch (\Exception $e) {
return $e->getMessage();
}
$form->sessionMessage('Danke für die Newsletter Anmeldung', 'good');
return $this->redirectBack();
}
}
NewsletterFormExtension.php
class NewsLetterFormExtension extends DataExtension {
private static $allowed_actions = [
'NewsletterForm'
];
public function NewsletterForm() {
$f = new NewsletterForm($this, 'NewsletterForm');
return $f;
}
}
Related
I am using REST API in my project and everything works great. I describe a model using a model
<?php
namespace api\modules\v1\models;
use Carbon\Carbon;
use Yii;
class Comment extends \common\models\Comment
{
public function fields()
{
return [
'id',
'user' => function(Comment $model) {
return User::findOne($model->user_id);
},
'text',
'image' => function(Comment $model) {
return Yii::$app->params['link'].$model->image;
},
'created_at' => function(Comment $model) {
Carbon::setLocale(Yii::$app->language);
return Carbon::createFromTimeStamp(strtotime($model->created_at))->diffForHumans();
},
'children' => function(Comment $model) {
$comments = Comment::find()
->where(['comment_id' => $model->id]);
if (!$comments->exists()) {
return false;
}
return $comments->all();
},
'like',
'news_id',
'comment_id'
];
}
}
The data is returned in the specified format and that's great. But I need to send data to the controller using websockets. For example, when a new comment arrives, send it to all users.
$post = Yii::$app->request->post();
$image = UploadedFile::getInstanceByName('image');
$model = new \api\modules\v1\models\Comment([
'news_id' => $post['feed_id'],
'comment_id' => $post['comment_id'] ?? null,
'user_id' => Yii::$app->user->identity->id,
]);
$model->text = $model->findLinks($post['text']);
if ($image && !$image->error) {
if (!file_exists(Yii::$app->params['comment.pathAbsolute'])) {
if (!FileHelper::createDirectory(Yii::$app->params['comment.pathAbsolute'], 0777)) {
throw new \Exception('Помилка створення папки');
}
}
$serverName = Yii::$app->security->generateRandomString(16).'.'.$image->extension;
if ($image->saveAs(Yii::$app->params['comment.pathAbsolute'].$serverName)) {
$model->image = $serverName;
} else {
throw new \Exception($image->error);
}
}
if (!$model->save()) {
throw new \Exception($model->error());
}
Helper::ws(false, 'updateComment', ['feed_id' => $post['feed_id'], 'comment' => $model]);
And when I pass the $model, the data is passed as it is stored in the database. Is it possible to call a method or something so that the data is passed as I described in the model api?
I populated the country list in my select option and when I click on country in user menu data save successfully and afterward while updating the user field the country name is not showing/or the old list from api loads this happens in laravel 08
Code to populate select option
document.addEventListener('DOMContentLoaded', () => {
const selectDrop = document.querySelector('#countries');
// const selectDrop = document.getElementById('countries');
fetch('https://restcountries.com/v3.1/all').then(res => {
return res.json();
}).then(data => {
let output = "";
data.forEach(country => {
console.log(country.name.common)
output += `<option value="${country.name.common}">${country.name.common}</option>`;
})
selectDrop.innerHTML = output;
}).catch(err => {
console.log(err);
})
});
here is my controller
public function update(Request $request){
try{
$user= User::data_update($request);
return view ('profile_edit', ['user'=>$user]);
}catch (\Exception $exception){
return $exception;
}
}
here is my model
public static function data_update($user1)
{
$user = self::user_data();
$user->name = $user1['name'];
$user->email = $user1['email'];
$user->phone = $user1['phone'];
$user->gender = $user1['gender'];
$user->country = $user1['country'];
$status = $user->save();
return $user;
}
here is my blade
<div class="col-sm-9 text-secondary">
<select id="countries" name="country">
<option value="{{$user->country}}" selected ></option>
</select>
</div>
I have override actionIndex() method. Now i want to use expand in param. My code is here
public function actions() {
$actions = parent::actions();
unset($actions['index']);
unset($actions['create']);
unset($actions['update']);
unset($actions['delete']);
return $actions;
}
public function actionIndex() {
$query = $this->model::find();
$query->someCondition()->all();
return $query
}
My Model is
public function fields() {
return [
'id',
'name',
];
}
public function extraFields() {
return ['status'];
}
Thanks
I want to save my image in db it is uploaded but not saved in my database any one know how to fix this
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$fname = UploadedFile::getInstance($model, 'imageFile');
if (!empty($fname)) {
$temp_path = Yii::$app->basePath . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR;
$model->save();
$fname->saveAs($temp_path . $fname);
$model->imageFile = $fname->name;
// echo '<pre>'; print_r($fname->name);
//exit();
}
if ($model->save()) { // To save the title to the database
Yii::$app->getSession()->addFlash('success', 'Image uploaded');
return $this->redirect(['index']);
}
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
Forgive my English.
I want to redirect not from action side but from a other function.
controller
public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getEntityManager();
$article = $em->getRepository('MySampleBundle:Article')->find($id);
// TODO:
// Since other actions have the same processing,
// I would like to do check work in other function.
// And when inaccurate,
// I want to make it move from that function to other page.
$this->is_edit_granted($article);
$form = $this->createForm(new ArticleType(), $article);
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
// ...
}
}
return $this->render('MySampleBundle:Article:edit.html.twig', array(
'form' => $form->createView(),
'article' => $article,
));
}
public function is_edit_granted($article)
{
// TODO:
// I check not at the action side but at this place,
// and want to make it move from this function to other page.
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
return $this->redirect( // doesn't work here
$this->generateUrl('home', array(
"id" => $article->getId()
))
);
}
}
I also tried similar code:
use Symfony\Component\HttpFoundation\RedirectResponse;
class SampleController extends Controller
{
// ...
public function editAction(Request $request, $id)
{
// ...
$this->is_edit_granted($article);
// ...
}
public function is_edit_granted($article)
{
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
return new RedirectResponse(
$this->generateUrl('home', array(
"id" => $article->getId()
))
);
}
}
}
but it doesn't work.
It is performing in the environment of Symfony 2.1.2.
How can I manage to achieve that?
Or, is there any better method?
Do something like:
public function editAction(Request $request, $id)
{
// ...
$response = $this->is_edit_granted($article);
if ($response) return $response;
// ...
}
public function is_review_granted($article)
{
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
return new RedirectResponse(
$this->generateUrl('home', array(
"id" => $article->getId()
))
);
}
return null;
}
It is not possible to redirect from the is_review_granted without returning the RedirectResponse form the editAction. So the answer of Carlos Granados is correct.
Another option would be to throw an AccessDeniedException in the is_review_granted method:
public function is_review_granted($article)
{
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
throw new Symfony\Component\Security\Core\Exception\AccessDeniedException('no acces');
}
}
You could also look to some more in-depth solutions like ACL and SecurityVoters.