Validation Drupal Form doesn't works - forms

I created these two functions to be able to modify the validation of my Drupal form by following different subjects on SOF or other information. But my query never goes into the validate function, and I do not understand why ...
/**
* Implements hook_form_FORM_ID_alter().
*/
function *****_form_simplenews_block_form_1_alter(&$form, &$form_state) {
// Modify some form settings
$form['mail']['#title_display'] = 'invisible';
$form['mail']['#size'] = 40;
$form['mail']['#attributes']['placeholder'] = t('Enter your email address');
$form['submit']['#value'] = t('OK');
$form['#validate'][0] = '*****_simplenews_block_form_validate';
}
/**
* Validate the mail address for simplenews
*
* #param $form
* #param $form_state
*/
function *****_simplenews_block_form_validate($form, &$form_state) {
kpr($form);die();
if (!valid_email_address($form_state['values']['mail']) && $form_state['values']['check_robot']) {
form_set_error('mail', t("Error, please try again"));
form_set_error('submit', "You are a robot.");
}
}
I went to see on the doc of the Drupal API (https://www.drupal.org/files/fapi_workflow_7.x_v1.1.png) , and it seems that I do what it is necessary, so if someone could help me, I would be rather happy, thank you in advance!

Well, my bad !
The action form submit the form to a webservice. So it will never been validated by the Drupal form workflow.

Related

MailChimp Campaign Content Update

MailChimp campaign content docs - https://developer.mailchimp.com/documentation/mailchimp/reference/campaigns/content
I'm trying to replace some placeholders in a campaign content with actual values via the API. At first, I thought there might be some syntax errors or internal logic errors like non-unique mc:edits into a mc:repeatable that would get the HTML refused/declined by MailChimp, hence the update not taking place, however, that was not the case.
Tried replacing html with a simple <p>test</p> and it was still not working.
Here are a couple of local logs, I'll use xyz as my campaign id:
2018-02-26 16:26:13 [::1][9804][-][warning][application] calling GET /campaigns/xyz/content []
2018-02-26 16:26:13 [::1][9804][-][warning][application] got both plain_text and html versions of content
2018-02-26 16:26:13 [::1][9804][-][warning][application] calling PUT /campaigns/xyz/content {"html":"<p>test</p>"}
2018-02-26 16:26:14 [::1][9804][-][warning][application] got response [
'plain_text' => 'test' + other MailChimp stuff such as footer, that were appended automatically by MailChimp,
'html' => '<p>test</p>'
]
// calling GET immediately after PUT in order to see if any update occurred
2018-02-26 16:26:14 [::1][9804][-][warning][application] calling GET /campaigns/xyz/content []
2018-02-26 16:26:14 [::1][9804][-][warning][application] got updated html (my "test" paragraph + auto footer from MailChimp) and proper plain_text
Everything looks fine according to these, that means both versions updated as they were supposed to. However, on the next API/MailChimp dashboard request, it displays the old HTML content, preserving the update I've just made in the plain text version only.
No errors, nothing to look into. It could be any internal MailChimp behaviour.
PS: I know about Setting Mailchimp campaign content html not working or MailChimp API v3 campaign content template sections, but none of the answers provided to those are helpful.
PS2: I know I should contact MailChimp, but according to
Our MailChimp Support Team isn't trained at in-depth API troubleshooting. If you need a developer to help you configure something using the API, check out our great Experts Directory, which lists third-party MailChimp experts who can be hired to help out.
they don't provide support for API troubleshooting.
MailChimp doesn't allow updating the campaign's HTML content because the campaign type is based on a template.
In order to update the HTML content, the campaign has to be set to custom HTML instead of a template. You can check the type by sending a GET API request to /campaigns or /campaigns/{campaign_id} and finding the content_type attribute in the response (documentation).
Alternatively, in the dashboard, the type can be determined by editing the design of the email. Anything under 'Code your own' is HTML and templates are of course templates.
I'm not entirely sure why the first response to a PUT request on a template campaign shows the updated content, but changing the content type should let you update as you want to.
Hope this helps!
If anyone's still looking for an answer to this.
I managed to solve the issue several weeks ago without creating the campaign via API, but actually updating it.
I used placeholders like [product_card id=123], 3 cards per block/row, all repeatable, which are wrapped in a class that I named product-card. In the MailChimp dashboard, you may still see the placeholders, but on preview and any form of preview like thumbnail, it will display correctly.
On the server, I crawl through the campaign's content, "detect" section names based on how they seemed to me in MailChimp and update each section with the content that I want.
PHP snippet below, some Yii2 stuff, but mostly plain PHP. I use $preview to display a preview of how the template would look, I know it's not visible in the function.
/**
* #param $id - Id of the campaign
* #param $s - Whether to save or just preview
*
* #return bool
*/
function changeContent($id, $s = false)
{
$mcCampaign = new McCampaign();
$mcCampaign::$itemId = $id;
$content = $this->api->get("/campaigns/{$id}/content");
if (!isset($content['html'])) return false;
$template = $content['html'];
$forgedDom = new \DOMDocument();
$forgedDom->loadHTML($template);
$mcSections = [];
$finder = new \DOMXPath($forgedDom);
$nodes = $finder->query('//td[contains(#class, "product-card")]');
// disabling this shit in order to avoid strict errors
libxml_use_internal_errors(true);
$mcEditId = 1;
$mcEditIndex = 0;
foreach ($nodes as $key => $node) {
/** #var \DOMElement $node */
$textContent = $node->textContent;
if (!preg_match("#\[product_card id=\d+\]#", $textContent)) continue;
$productId = filter_var($textContent, FILTER_SANITIZE_NUMBER_INT);
$node->textContent = false;
$product = Product::findOne($productId);
$productDetails = $product ? $this->renderPartial('/partials/_mc-product', [
'product' => $product
]) : 'Product not found.';
if ($key != 0) {
if ($key % 3 == 0) {
$mcEditId = 1;
$mcEditIndex++;
} else {
$mcEditId++;
}
}
$mcSections["repeat_1:{$mcEditIndex}:product_card_{$mcEditId}"] = $productDetails;
$fragment = $forgedDom->createDocumentFragment();
$fragment->appendXML($productDetails);
$node->appendChild($fragment);
}
libxml_use_internal_errors(false);
$preview = $forgedDom->saveHTML();
// just in case
/* $preview = str_replace(["\n", "\t", "\r"], "", $preview); */
if ($s) {
if (!empty($mcSections)) {
$res = $this->api->put("/campaigns/{$id}/content", [
'template' => [
'id' => *template_id_here*,
'sections' => $mcSections
],
]);
// forcing Mc to rebuild cache
$this->api->get("/campaigns/{$id}/content");
Yii::$app->session->setFlash('success', 'Done.');
return $this->redirect(['campaign/index']);
} else {
Yii::$app->session->setFlash('error', 'Something went wrong.');
}
}
}

PhpUnit form does not submit, no error

I'm doing a functional test in PhpUnit to test simple modal window functionality which has only one field and two buttons (i have tried various ways so the code may be not clean, I'm pasting just to show the idea):
$form = $crawler
// find all buttons with the text "Pridėti"
->filter('button:contains("Pridėti")')
->eq(0)
->form()// select the first button in the list
;
$form['appbundle_classinfo[name]'] = '5a';
$crawler = $client->submit($form);
//It doesn't even save to database
$container = self::$kernel->getContainer();
$em = $container->get('doctrine')->getManager();
$classinfo = $em->getRepository('AppBundle:ClassInfo');
//Echoes modal window
echo $client->getResponse()->getContent() ;die;
I also tried to var_dump the form, it shows that the value is added to form:
string(25) "appbundle_classinfo[name]"
["value":protected]=>
string(2) "5a"
So the form is not submitted. Can you help me find out why?
<?php
namespace AppBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PostTest extends WebTestCase
{
public function testShowPost()
{
//returns a Client, your browser use your web site
$client = static::createClient();
// The request() method (read more about the request method) returns a Crawler object which can be used to select elements in the response, click on links and submit forms.
$crawler = $client->request('GET', '/your/route/controller/action');
// select button by name or id
$form = $crawler->selectButton('Login')->submit();
//submit the form
$crawler->submit($form);
$this->assertGreaterThan(
0,
$crawler->filter('html:contains("hello world")')->count()
);
// get HTML content returned
dump($client->getResponse()->getContent());
}
http://symfony.com/doc/current/testing.html#functional-tests
hope that were useful, let me know.

Magento2: is there a product list limit?

In an existing Magento2 shop I have a category that contains a lot of products (over 2000). But when I click on it, only the first 190 of them are shown. Is there any way to set that limit, and if so, where?
Or is there an other reason why my products list is limited to 190 products? Any ideas?
You can get the 190 product form below script
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
/** #var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */
$productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Collection');
/** Apply filters here */
$productCollection->addAttributeToSelect('*')
$productCollection->setPageSize(190)
$productCollection->load();
Used setPageSize() and setCurPag‌​e()
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$data = $objectManager->create('Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection')->setPageSize(10)->setCurPag‌​e(1);

Use tt_address fields in direct_mail newsletter

I am using TYPO3 6.2.11, tt_address 2.3.5 and direct_mail 4.0.1 and sent me some test newsletters from a internal TYPO3-Page. Everything works fine.
Now, I want to send some data fields from my tt_address-table like name or title for example.
What's the name of the tt_address-MARKER, I'll use at my page content?
I also add the follwing to [basic.addRecipFields] at the direct_mail-Extension:
name,first_name,last_name,email,description,title
But nothing happens. I can't use tt_address-fields at my direct_mail newsletter. I hope someone can help me, thanks.
The other opportunity is to use fe_user-data for my newsletter (felogin). How can I use felogin-fields like passwordor username at my template?
You need to prefix the fields with USER_ and wrap the marker in ###. So e.g. if you'd like to use the e-mail address, you write ###USER_email###. You can find all possibilities in the Direct Mail documentation.
A note on sending the password: This would be a huge security risk but it's not possible anyway because passwords of fe_users are stored at least hashed (and nowadays also encrypted) in the database. But you can use the ###SYS_AUTHCODE### marker to generate an authentication code you can use in an "edit profile" extension to let the user update his subscription.
If you need fields from other sources or data you're calculating dynamically, you can also create an own extension and implement the Direct Mail mailMarkersHook.
ext_localconf.php:
// Direct Mail personalization hook
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/direct_mail']['res/scripts/class.dmailer.php']['mailMarkersHook']['userunilunewsletterrendering'] =
'My\Extension\Hook\DirectMail->mailMarkersHook';
EXT:extension/Classes/Hook/DirectMail.php:
<?php
namespace My\Extension\Hook;
class DirectMail {
public function mailMarkersHook($params, \DirectMailTeam\DirectMail\Dmailer $dmailer) {
$params['markers']['###USER_SALUTATION###'] = $this->getPersonalizedSalutation($params['row']);
return $params;
}
/**
* #param $row
* #return string
*/
protected function getPersonalizedSalutation($row) {
$personalizedSalutation = 'Dear Sir or Madam';
if (!empty($row['last_name']) && !empty($row['gender'])) {
if ($row['gender'] === 'm') {
$personalizedSalutation = 'Dear Mr. ' . $row['last_name'];
} elseif ($row['gender'] === 'f') {
$personalizedSalutation = 'Dear Ms. ' . $row['last_name'];
}
}
return $personalizedSalutation;
}
}

Behat + mink how to test jquery-ui autocomplete field?

I'm using Behat to test a registration page.
This page contains a few fields with autocompletion.
User fills in some value in the field, page waits 500 milliseconds, makes an ajax-request and displays some options along with a relevant message (no items found / several items found / one item found).
I'm using a predefined step "I fill in field with value" (tried to use "I fill in value for field" instead).
Next step is custom, similar to one described in documentation - I'm just waiting for message to appear and check that it has correct text.
But after filling the field Mink removes focus from it, causing blur event to be fired on the field.
Jquery-ui clears the field value in response to this blur event, so after 500 milliseconds field is empty and ajax request is aborted.
How can I fix this problem?
Behat v2.5.0
Mink v1.5.0
Mink-extension v1.3.3
Jquery-ui v1.8.21
Selenium v2.44.0
Solution below is specific to my markup code but should be easily adapted to yours. You might need to modify it.
Assuming that selecting auto suggested option in textbox. Autosuggestion options appear as <li> elements after user’s key strokes. <li> element presents in the page however its content is empty at the beginning so there is nothing to be selected by behat. To solve the problem, non existing content between <li> tags is wrapped with <label> tag.
User types in this auto suggestion field:
<input name="brand" type="text" />
Where autosuggestion data appears:
<ul>
<li><label>{{ suggestion }}</label></li>
</ul>
Gherkin:
When I fill in "brand" with "S"
And I wait 1 seconds
Then I select autosuggestion option "Sula"
And I wait 1 seconds
......
FeatureContext:
/**
* #Given /^I wait (\d+) seconds$/
*/
public function iWaitSeconds($seconds)
{
sleep($seconds);
}
/**
* #Then /^I select autosuggestion option "([^"]*)"$/
*
* #param $text Option to be selected from autosuggestion
* #throws \InvalidArgumentException
*/
public function selectAutosuggestionOption($text)
{
$session = $this->getSession();
$element = $session->getPage()->find(
'xpath',
$session->getSelectorsHandler()->selectorToXpath('xpath', '*//*[text()="'. $text .'"]')
);
if (null === $element) {
throw new \InvalidArgumentException(sprintf('Cannot find text: "%s"', $text));
}
$element->click();
}
#Scenario: I'm stuck
Given I use jquery-ui-autocomplete
And I can not test it with behat
Then I trigger keyDown event like this:
"""
/**
* #When I select :entry after filling :value in :field
*/
public function iFillInSelectInputWithAndSelect($entry, $value, $field)
{
$page = $this->getSession()->getPage();
$field = $this->fixStepArgument($field);
$value = $this->fixStepArgument($value);
$page->fillField($field, $value);
$element = $page->findField($field);
$this->getSession()->getDriver()->keyDown($element->getXpath(), '', null);
$this->getSession()->wait(500);
$chosenResults = $page->findAll('css', '.ui-autocomplete a');
foreach ($chosenResults as $result) {
if ($result->getText() == $entry) {
$result->click();
return;
}
}
throw new \Exception(sprintf('Value "%s" not found', $entry));
}
"""
Use this to Fill in the search box: (using the ID selector)
/**
* #Then I type :text into search box
*/
public function iTypeTextIntoSearchBox($text)
{
$element = $this->getSession()->getPage()->findById('searchInput');
$script = "$('#searchInput').keypress();";
$element->setValue($text);
$this->getSession()->evaluateScript($script);
}