Codeigniter custom helper for bbcode, apply function on parameter - codeigniter

I made a custom bbcode parser function and added it on my helper
if ( !function_exists('bbcode_parser'))
{
function bbcode_parser($str)
{
$patterns = array(
'#\[b\](.*?)\[/b\]#is',
'#\[img\](.*?)\[/img\]#is',
'#\[url\](.*?)\[/url\]#is',
'#\[url=(.*?)\](.*?)\[/url\]#is'
);
$replacements = array(
'<strong>$1</strong>',
'<img src="$1" />',
'$1',
'$2',
);
$str = preg_replace($patterns, $replacements, $str);
return $str;
}
}
It's good and works like I want it to but my question is how to apply a function on each replacement value.
fe. for the url that doesn't have inner data, i want to replace with the website title of the url
or validate the url if it has http://
i would also like to check the size of the image, if it's too large, i want to resize it when printed by adding a "width" attribute and then just add an tag to the full size image.
is this possible? if so, how to do this?

You can implement this with preg_replace_callback()
http://www.php.net/manual/en/function.preg-replace-callback.php
Only the matched elements will be passed to the callback, so you would be able to create the callbacks you need or apply a standard replace for the normal regex patterns.

Related

How to fill a rich text editor field for a Codeception Acceptance test

I'm trying to fill a rich text editor field (TinyMCE) within my acceptance test in Codeception.
Using the fillField() function doesn't work as this 'field' isn't really an input field. It's an iframe, styled to look like a fancy textarea.
How can I set some text into the body of the TinyMCE box? I think I'm looking for the addition of a $I->setContent(xpathOrCSS) function. Or does something else already exist to do this?
It is best to do this by adding re-usable actions to your Actor class (AcceptanceTester, by default). You can then use the actions in your tests to set the content of rich text editor fields without reducing the readability of your tests. More details on this are available in the Codeception documentation.
I have included solutions for TinyMCE and CKEditor below. The solution uses the executeInSelenium() call to give us access to Facebook's underlying WebDriver bindings. From there, we simply use the frame switching/Javascript injection technique described here to set the content of our target editor.
Note that the final call to $webDriver->switchTo()->defaultContent() is very important - this switches WebDriver's focus back from the RTE iframe to the page that contains it.
Actor functions:
<?php
class AcceptanceTester extends \Codeception\Actor {
use _generated\AcceptanceTesterActions;
public function fillCkEditorById($element_id, $content) {
$this->fillRteEditor(
\Facebook\WebDriver\WebDriverBy::cssSelector(
'#cke_' . $element_id . ' .cke_wysiwyg_frame'
),
$content
);
}
public function fillCkEditorByName($element_name, $content) {
$this->fillRteEditor(
\Facebook\WebDriver\WebDriverBy::cssSelector(
'textarea[name="' . $element_name . '"] + .cke .cke_wysiwyg_frame'
),
$content
);
}
public function fillTinyMceEditorById($id, $content) {
$this->fillTinyMceEditor('id', $id, $content);
}
public function fillTinyMceEditorByName($name, $content) {
$this->fillTinyMceEditor('name', $name, $content);
}
private function fillTinyMceEditor($attribute, $value, $content) {
$this->fillRteEditor(
\Facebook\WebDriver\WebDriverBy::xpath(
'//textarea[#' . $attribute . '=\'' . $value . '\']/../div[contains(#class, \'mce-tinymce\')]//iframe'
),
$content
);
}
private function fillRteEditor($selector, $content) {
$this->executeInSelenium(
function (\Facebook\WebDriver\Remote\RemoteWebDriver $webDriver)
use ($selector, $content) {
$webDriver->switchTo()->frame(
$webDriver->findElement($selector)
);
$webDriver->executeScript(
'arguments[0].innerHTML = "' . addslashes($content) . '"',
[$webDriver->findElement(\Facebook\WebDriver\WebDriverBy::tagName('body'))]
);
$webDriver->switchTo()->defaultContent();
});
}
}
Example Usage:
$content = '<h1>Hello, world!</h1>';
// CKEditor
$I->fillCkEditorByName('rich_content', $content);
$I->fillCkEditorById('my_ckeditor_textarea', $content);
// TinyMCE
$I->fillTinyMceEditorByName('rich_content', $content);
$I->fillTinyMceEditorById('my_tinymce_textarea', $content);
In all cases, the first parameter refers to the name/id attribute of the original textarea element, and the second parameter is the HTML content to fill it with.
Best way:
$I->executeJS('$("#selector").val("Value")');
If you have a simple setup and only need to test one instance in tinyMCE 4, this worked for me.
$I->executeJS('tinyMCE.activeEditor.setContent(" your content goes here ");');
IF you have and iframe like this:
<iframe id="myFrameID" allowtransparency="true"></iframe>
notice, that Codeception switches to the iframe using
$I->switchToIFrame("myFrameID");
Keep in mind, to omit the # in front of "myFrameID", as switch to iframe does not use a css selector but rather just the name of the iframe.
Then do
$I->executeJS('document.getElementById("tinymce").innerHTML = "<p>Some Text Here!</p>";');
and don't forget to switch back to previous window:
$I->switchToIFrame();
as stated in
https://codeception.com/docs/modules/WebDriver#switchToIFrame
Tried and following solution works:
$I->switchToIFrame('#frameName');
$I->executeJS('document.getElementById("tinymce").innerHTML = "<p>Test abc def</p>";');
try this
$x = $I->grabAttributeFrom('//iframe', 'id');
$I->switchToIframe($x);
$I->fillField('//*[#id="tinymce"]', '<p>Test abc</p>');

Codeigniter add validation for multiple element

My form has more than 50 different text inputs. I would like to use CodeIgniter's validations (like trim function) in the form validation library without creating a rule for each input. Is it to possible to combine them into one rule so I don't have to waste my time writing the same code over and over?
Change text field name as group_name[your_txt_names] in your view
<input name="group_name[your_txt_names]" value="" type="text" />
Then in controller, you can create a function.
$txt_bxes = $this->input->post("group_name");
$post_vals = array_map('trim', $txt_bxes);
Now you have trimmed values in your array.
Kumar_v's idea was on the right track, if a bit silly in implementation
$this->input->post('var); merely reads the $_POST and runs some sanitation on it; the validation rules merely read the var from $_POST and apply your validation rule.
So if you only want to trim all $_POST vars, just trim your $_POST directly, then you can also run other validation afterwards.
Solution:
$_POST = array_map('trim', $_POST);
or
// take all posts and dump them into a variable at once
$input = $this->input->post(null, true);
$input = array_map('trim', $input);
as the post data comes in array, I hope this will help you
$postData = $this->input->post();
array_walk($postData ,'myFunc');
function myFunc(&$value,$key){
$value = trim($value);
}

Drupal 7 ajax_command_* creates unwanted div

I'm populating a select box using an AJAX callback in Drupal 7. I've tried both ajax_command_append() and ajax_command_html() to set the new <option...> statements, but both these wrap the HTML that I create inside a <div>. This causes the <select> to not display any of the options.
Is there a way to tell Drupal "Hey stupid, this is exactly the HTML I want, don't mess with it"?
I can code some jQuery to remove the div I guess, but it would be a lot better if I can prevent it from being added in the first place.
Yes you can!
Declare your own custom js callback. In below example, I used a span instead of the divs. But you can obviously remove the wrapper alltogether.
PHP:
function my_ajax_callback() {
$data = 'saved!';
// instead of using ajax_command_html, we provide our own
// js custom callback function
$output = array(
'#type' => 'ajax',
'#commands' => array(
array('command' => 'myjscallback', 'data' => $data),
),
);
return $output;
}
JS:
$(function() {
Drupal.ajax.prototype.commands.myjscallback = function (ajax, response, status) {
$('#save-btn-message').html('<span>' + response.data + '</span>');
};
});
The answer is yes.
Just use this instead:
$commands[] = ajax_command_invoke('#mywrapper', 'html', array($output));
So it seems the answer is "no" (or at least not without hacking core, and I'll have no dead kittens on my conscience).
misc/ajax.js contains the following:
var new_content_wrapped = $('<div></div>').html(response.data);
The comments therein go on to explain why they require the first HTML element to be a top-level one. If it is, the <div> wrapper is not used. In my case, I'm replacing <option> elements, so I get the <div>.
Now I could just replace the entire <select>, but that causes other issues in my case due to scripts that style things at page load. Rather than find those and re-fire them, it looks like it'll be easier to just ajax_command_invoke a script to run after my options are loaded to remove the div wrapper.
EDIT: As a workaround, I found I can do ajax_command_invoke($selector, 'html', array('<option...>')); and it bypasses the div addition code. Kinda sneaky, but it works...
you can use seen on this link http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#ajax
for more reference and example download this module http://drupal.org/project/examples
it has all the examples of custom code and "ajax_example" as well
It works for me!
$selector = '#my-select';
$method = 'append';
$opts = array('new option');
$commands[] = ajax_command_invoke($selector, $method, $opts);
return array('#type' => 'ajax', '#commands' => $commands);

Codeigniter form validation allow numeric type to include comma

When validating prices with CI I use the following rule;
$this->form_validation->set_rules('price','lang:price','required|numeric|greater_than[0.99]');
Is there any way to allow commas in this rule line? Or do i have to create a callback?
Codeigniter 3 offers a regex validation. Form Validation
Using the regex given by Ben... No callback is required.
$this->form_validation->set_rules('price','lang:price','required|numeric|greater_than[0.99]|regex_match[/^[0-9,]+$/]');
From using the form validation library, I've never seen anything that would allow you to do that without a callback.
This would be the callback though:
function numeric_wcomma ($str)
{
return preg_match('/^[0-9,]+$/', $str);
}
with a rule of
$this->form_validation->set_rules('input', 'Input', 'callback_numeric_wcomma');
My answer is:
$this->form_validation->set_rules('price','lang:price','regex_match[/^(?!0*[.,]?0+$)\d*[.,]?\d+$/m]');
or do it in your codeigniter view. Add script:
<script>
function replace(element) {
// set temp value
var tmp = element.value;
// replace everything that's not a number or comma or decimal
tmp = tmp.replace(/[^0-9,.,-]/g, "");
// replace commas with decimal
tmp = tmp.replace(/,/, ".");
// set element value to new value
element.value = tmp;
}
</script>
and then use input like this:
<input id="something" onkeyup="replace(this)" type="text">

Joomla TinyMCE editor do not save inserted image

We are building joomla component. And we use joomla editor in which we insert content.
But there is a problem, because when we add image to editor and save it, it do not add image to database and when we opening this element to edit it again, there is only text in editor, image disappears.
This is how we use it:
$editor =& JFactory::getEditor();
echo $editor->display('text', $this->hello->text, '800', '300', '20', '20');
Maybe there is need to supply aditional parameters to display method?
Problem solved.
The standard way of getting the form data $post = JRequest::get('post'); is not enough in the case of using a editor. This will filter the content, hence losing line breaks and paragraps. So we need to add an extra line to get the editor contents in a raw unfiltered way. This data will be passed to the model to save into the database.
To get HTML form post data you need to get this data in following way
$data = JRequest::getVar( 'editorName', 'defaultValue', 'post', 'string', JREQUEST_ALLOWRAW );
And need to add a javascript for the view(tmpl file)
function submitbutton(action) {
var form = document.adminForm;
switch(action)
{
case 'save':case 'apply':
<?php
$editor =& JFactory::getEditor();
echo $editor->save( 'editorName' );
?>
case 'publish':
case 'unpublish':
case 'cancel':
default:
submitform( action );
}
}

Resources