how can i validate the bill address depending on bill_ceck post parameter?
i reviewed the post validation (http://symfony.com/legacy/doc/cookbook/1_2/en/conditional-validator) but it seem to me like an AND validation not an OR.
class OrderAddForm extends BaseOprOrderHeaderForm {
public function configure() {
$this->setWidgets(array(
'email' => new sfWidgetFormInputText(),
'name' => new sfWidgetFormInputText(),
//....
'city' => new sfWidgetFormInputText(),
'street' => new sfWidgetFormInputText(),
//....
'bill_check' => new sfWidgetFormInputCheckbox(),
'bill_name' => new sfWidgetFormInputText(),
'bill_city' => new sfWidgetFormInputText(),
'bill_street' => new sfWidgetFormInputText(),
//....
));
$this->widgetSchema['bill_check']->setOption('value_attribute_value', 1);
$this->setValidators(array(
'email' => new sfValidatorEmail(),
'name' => new sfValidatorString(),
//...
'city' => new sfValidatorString(),
'street' => new sfValidatorString(),
//...
'bill_check' => new sfValidatorBoolean(),
));
if (/** the most convetional solution to check 'bill_check' state */) {
$this->validatorSchema['bill_name'] = new sfValidatorString();
$this->validatorSchema['bill_city'] = new sfValidatorString();
$this->validatorSchema['bill_street'] = new sfValidatorString();
//....
}
$this->widgetSchema->setNameFormat('orderAddForm[%s]');
}
}
thanks,
oliver
You could use a postValidator
public function configure() {
// your current code
$this->validatorSchema->setPostValidator(
new sfValidatorCallback(array('callback' => array($this, 'checkOtherStuff')))
);
}
public function checkOtherStuff($validator, $values)
{
// $values is an array of POSTed values
if ($values['bill_check'] == 'something in here')
{
if ($values['bill_city'] == '' || $values['bill_street'] == '') {
throw new sfValidatorError($validator, 'You must complete all fields');
}
}
// bill_check is correct, return the clean values
return $values;
}
Blog article on the subject here
Related
I know that segments are not supported in the current v1Beta api (https://analyticsdata.googleapis.com/v1beta/properties/{property_id}:runReport).
Is there a workaround to get segmented data from using this api?
Reference: https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
I was working with google analytics API GA4 using PHP hope this helps you
<?php
class analytics{
private $property_id =null;
private $client = null;
public $propertys;
public function setPropertyId($propertyid)
{
return $this->property_id = $propertyid;
}
private function getCredentials()
{
return DIR.'PATH/credentials.json');
}
private function getClient(): BetaAnalyticsDataClient
{
return $this->client= new BetaAnalyticsDataClient([
'credentials' => $this->getCredentials(),
]);
}
public function get($propertyid,$startdate,$enddate,dimensions,$metrics)
{
$response = $this->getClient()->runReport([
'property' => 'properties/' . $this->setPropertyId($propertyid),
'dateRanges' => [
new DateRange([
'start_date' => $startdate,
'end_date' => $enddate,
]),
],
'dimensions' => [new Dimension(
[
'name' => $dimensions,
]
),
],
'metrics' => [new Metric(
[
'name' => $metrics,
]
)
]
]);
foreach ($response->getRows() as $row) {
return $row->getMetricValues()[0]->getValue();
}
}
}
then you can use the get function with dates range and dimensions metrics you want
I'm trying to save my ManyToMany relations between users and categories. Actually I'm trying to save my category with given users, but this doesn't work.
Form
$builder->add('name')
->add('users', EntityType::class, array(
'label' => 'Benutzer',
'class' => 'AppBundle\Entity\User',
'multiple' => true,
'expanded' => true,
'required' => false,
'choice_label' => function (User $user) {
return $user->getUsername();
}
))
->add('submit', SubmitType::class, array(
'label' => 'Speichern'
));
Form Handler
public function onSuccess(Request $request)
{
// Get category from form
$category = $this->getForm()->getData();
// Redirect to parent category when setted
if ($this->parent) {
$category->setParent($this->parent);
$response = new RedirectResponse($this->router->generate('categories.view', [
'category' => $this->parent->getId()
]));
} else {
// Build new redirect response
$response = new RedirectResponse($this->router->generate('categories.view', [
'category' => $category->getId()
]));
}
try {
// Save category in database
$this->em->merge($category);
$this->em->flush();
} catch (ORMException $ex) {
throw $ex;
}
return $response;
}
Maybe you have to unserialize the Entity $category first?
$detachedCategory = unserialize($category);
$this->em->merge($detachedCategory);
$this->em->flush();
I found this link regarding that:
How to manage deserialized entities with entity manager?
Not sure if that's the answer, but you might want to do more research.
I wrote a custom views handler, that mark message private to 0 or 1 or 2; any is value of hers label [MARK_READ,ARK_NEW,...] :
function mydevel_views_data() {
$data['mydevel']['table']['group'] = t('mydevel');
$data['mydevel']['table']['join'] = array(
// Exist in all views.
'#global' => array(),
);
$data['mydevel']['mydevel_isnewmessage'] = array(
'title' => t('is new message field'),
'help' => t('is new message field.'),
'field' => array(
'handler' => 'mydevel_handler_field_isnewmessage',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'mydevel_handler_filter_isnewmessage',
),
);
and wrote a filed handler that work properly; message_mark function is wrote on mydevel module file and work currectly; if the message is new that filed label row by "now":
class mydevel_handler_field_isnewmessage extends views_handler_field_numeric {
var $field_alias = 'mydevel_field_isnewmessage';
function query() {
}
function option_definition() {
$options = parent::option_definition();
//dsm($this);
return $options;
}
function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
}
function get_value($values, $field = NULL) {
return intval(message_mark($values->mid, $values->message_timestamp));
}
function render($values) {
$value = $this->get_value($values);
$value_theme = theme('mark', array('type' => $value));
return $value_theme;
}
}
Now, i want to write a views filter handler that filter on that filed on numeric mode [0 or 1 or 2] or on check list mode [all, read, new, updated]. but I don't want to overwite query function on filter handler and want to use from value that returned by this common handler filed (mydevel_handler_filter_isnewmessage) that added to views filed. can wrote this idea by extend the standard views handler? what i do my dears? I wrote this but not work: this is return error
class mydevel_handler_filter_isnewmessage extends views_handler_filter_numeric {
var $always_multiple = TRUE;
function option_definition() {
$options = parent::option_definition();
return $options;
}
function operators() {
$operators = parent::operators();
return $operators;
}
function query() {
}
}
tank you a lot.
when i create a user with facebook-sdk, i don't get him logged in automaticaly after facebook-login.
Usercreation working well, but no login.
Cakephp and facebook-sdk are latest versions.
here is my accountController:
<?php
class AccountController extends AppController {
public $uses = array('User');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('login');
#$this->Auth->authenticate = array('Basic' => array('fields' =>array('username' => 'fb_id', 'password' => 'random')));
}
public function login() {
$this->facebook = new Facebook(array(
'appId' => '14549077xxxx',
'secret' => '95a38f3xxxx',
'cookie' => 'true'
));
$user = $this->facebook->getUser();
if($user){
try{
$params = array('next' => 'http://'.$_SERVER['HTTP_HOST'].'/account/logout');
$this->Session->write('logoutLink', $this->facebook->getLogoutUrl($params));
#if (!$this->Auth->user()) {
$fb_user = $this->facebook->api('/me');
$authUser = $this->User->findByFbId($user);
if (empty($authUser)) {
$pw = $this->__randomString();
$authUser = array(
'fb_id' => $user,
'random' => $pw,
'password' => $this->Auth->password($pw),
'email' => $fb_user['email']
);
$this->User->create();
$this->User->save($authUser);
$authUser = $this->User->findByFbId($user);
}
$this->Auth->authenticate = array(
'Form' => array(
'fields' => array('username' => 'fb_id', 'password' => 'random')
)
);
$this->Auth->login($authUser['User']);
$this->redirect($this->Auth->redirect());
#}
}catch(FacebookApiException $e){
$user = NULL;
}
}
if(empty($user)){
$loginurl = $this->facebook->getLoginUrl(array(
'scope'=> 'email,publish_stream,read_friendlists',
'redirect_uri' => 'http://'.$_SERVER['HTTP_HOST'].'/account/login',
));
$this->redirect($loginurl);
}
}
public function dashboard() {
echo 'logged in';
}
}
Users will always get redirect to login page.
$authUser is always filled correctly.
Pls Help :)
Greetings
m.
my AppController
class AppController extends Controller {
public $components = array('Auth','Session');
public function beforeFilter() {
$this->Auth->loginRedirect = array('controller' => 'account', 'action' => 'dashboard');
$this->Auth->logoutRedirect = '/';
$this->Auth->loginAction = array('controller' => 'pages', 'action' => 'login');
}
Sessions:
Configure::write('Session', array(
'defaults' => 'php'
));
problem solved in chat:
Facebook is creating a new session,
$this->facebook = new Facebook(array(
'appId' => '14549077xxxx',
'secret' => '95a38f3xxxx',
'cookie' => 'true'
));
this code has to written down in appcontroller
public function beforeFilter() {
$this->Auth->loginRedirect = array('controller' => 'account', 'action' => 'dashboard');
$this->Auth->logoutRedirect = '/';
$this->Auth->loginAction = array('controller' => 'pages', 'action' => 'login');
$this->facebook = new Facebook(array(
'appId' => '14549077xxx',
'secret' => '95a38f3xxx',
'cookie' => 'true'
));
}
Thank you so much #noslone for trying together :D
Providing data $this->Auth->login($authUser['User']); to log a user in is wrong.
As per CakePHP documentation:
In 2.0 $this->Auth->login($this->request->data) will log the user in with whatever data is posted, whereas in 1.3 $this->Auth->login($this->data) would try to identify the user first and only log in when successful.
You should do something like this:
$this->request->data['User'] = $authUser['User'];
$this->request->data['User']['password'] = $authUser['User']['random'];
$this->Auth->login();
I have also added $this->request->data['User']['password'] = $authUser['User']['random']; because i think it fails to authenticate when providing the encrypted password to login.
If you have any other trouble, I am developing a Plugin that uses Facebook oAuth as an authentication object for Auth Component. If you want an already-built solution that uses server-side Facebook login, please check my website: http://marianofino.github.com/Facebook-Plugin-for-CakePHP/
How to limit the number of embedded form with the type "sonata_type_collection" ?
$formMapper->add('phones', 'sonata_type_collection',
array(
'required' => true,
'by_reference' => false,
'label' => 'Phones',
),
array(
'edit' => 'inline',
'inline' => 'table'
)
I would like limit to last five phones, I found only this solution for now, limit the display in the template twig "edit_orm_one_to_many", but i don't like that.
I found a solution by rewriting the edit action in the controller,
such in the documentation sonataAdminBundle I created my admin controller class:
class ContactAdminController extends Controller
{
public function editAction($id = null)
{
// the key used to lookup the template
$templateKey = 'edit';
$em = $this->getDoctrine()->getEntityManager();
$id = $this->get('request')->get($this->admin->getIdParameter());
// $object = $this->admin->getObject($id);
// My custom method to reduce the queries number
$object = $em->getRepository('GestionBundle:Contact')->findOneAllJoin($id);
if (!$object)
{
throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
}
if (false === $this->admin->isGranted('EDIT', $object))
{
throw new AccessDeniedException();
}
$this->admin->setSubject($object);
/** #var $form \Symfony\Component\Form\Form */
$form = $this->admin->getForm();
$form->setData($object);
// Trick is here ###############################################
// Method to find the X last phones for this Contact (x = limit)
// And set the data in form
$phones = $em->getRepository('GestionBundle:Phone')->findLastByContact($object, 5);
$form['phones']->setData($phones);
// #############################################################
if ($this->get('request')->getMethod() == 'POST')
{
$form->bindRequest($this->get('request'));
$isFormValid = $form->isValid();
// persist if the form was valid and if in preview mode the preview was approved
if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved()))
{
$this->admin->update($object);
$this->get('session')->setFlash('sonata_flash_success', 'flash_edit_success');
if ($this->isXmlHttpRequest())
{
return $this->renderJson(array(
'result' => 'ok',
'objectId' => $this->admin->getNormalizedIdentifier($object)
));
}
// redirect to edit mode
return $this->redirectTo($object);
}
// show an error message if the form failed validation
if (!$isFormValid)
{
$this->get('session')->setFlash('sonata_flash_error', 'flash_edit_error');
}
elseif ($this->isPreviewRequested())
{
// enable the preview template if the form was valid and preview was requested
$templateKey = 'preview';
}
}
$view = $form->createView();
// set the theme for the current Admin Form
$this->get('twig')->getExtension('form')->renderer->setTheme($view, $this->admin->getFormTheme());
return $this->render($this->admin->getTemplate($templateKey), array(
'action' => 'edit',
'form' => $view,
'object' => $object,
));
}
}