I'm trying to hook into the hook_views_post_execute event in Drupal 7, my module called foo is located in sites/default/modules/features/foo.
My foo.module file contains a definition for the hook_views_api function, defined like this:
function foo_views_api() {
return array("version" => 3.0);
}
This function gets called, but my implementation of the hook_views_post_execute does not, it's defined (in the same foo.module file) like this:
function foo_views_post_execute(&$view) {
$seen_rows = array();
$newResults = array();
for($i = 0; $i < count($view->result); ++$i) {
if (!in_array($view->result[$i]->nid, $seen_rows)) {
$newResults[] = $view->results[$i];
}
$seen_rows[] = $view->result[$i]->nid;
}
$view->result = $newResults;
}
I've been over the drupal API/hooks documentation, googled and read every blog post I've been able to find. I just can't get it to work. The hook does not get called. I'm assuming I've done something simple wrong since I'm not a drupal developer or PHP developer normally.
The view has probably been cached so it doesn't go through that function.
Go to the top left and clear the cache and you should see the result.
Related
I have a function callFunctions() which basically calls various functions, say api1(), api2(), api3(), etc..
These functions make cURL requests to various APIs which return data which I then parse and merge into a globally declared array, say $finalData
Earlier i was calling these functions in linear order and each function took their own time to fetch results, parse and merge them into $finalData.
global $finalData = array();
callFunctions(){
api1();
api2();
..
..
api10();
}
But it takes a lot of time to get the final data due to large number of requests.
So, I tried to call these functions parallely using Multi-threading.
class ApiParallelQueries extends Thread {
public function __construct($i){
$this->i=$i;
}
public function run(){
selectApis($this->i);
}
}
function selectApis($i){
switch($i){
case 1: api1();break;
case 2: api2();break;
..
..
case 10: api10();break;
}
}
callFunctions(){
for($i = 1; $i <= 10; $i++){
$workers[$i] = new ApiParallelQueries($i);
$workers[$i]->start();
}
for($i = 1; $i <= 10; $i++){
$workers[$i]->join();
}
}
But the problem is, I'm not getting the result I was getting from the sequential function calls.
I'm not sure if it has something to do with global variables or not but i'm guessing thats the problem,
could it be some other issue? can we not make cURL requests with multithreading?
Note: I also noticed a strange thing while i was trying this, i tried to print timestamps and the time was different when the functions were called using multi-threading.
I have a custom component, in fact several. Each will have raw and hard-coded html at the beginning and end of their /view/default.php
I have a system plugin that needs to get this html and in some cases change it to something else, that can be managed in the back end. As a content plugin this works fine on all com_content articles, but it is ignored by components, my understanding is system plugins can do this but i can't get the data into the plugin and return it
example of component text ($text1, $text2 are defined at the top of the document)
JPluginHelper::importPlugin( 'system' );
JPluginHelper::importPlugin('plgSystemMyplugin');
$dispatcher =& JDispatcher::getInstance();
$data = array($text1, $text2); // any number of arguments you want
$data = $dispatcher->trigger('onBeforeRender', $data);
<article>
<div class="spacer" style="height:25px;"></div>
<div class="page_title_text">
<h1>title</h1>
<?php var_dump($data); ?>
</div>
<section>
my plugin:
jimport( 'joomla.plugin.plugin' );
class plgSystemMyplugin extends JPlugin {
function onBeforeRender() {
if (JFactory::getDocument()->getType() != 'html') {
return;
}
else {
$document=JFactory::getDocument();
$document->addCustomTag('<!-- System Plugin has been included (for testing) -->');
$document=JResponse::getBody();
$bob=JResponse::getBody();
$db = &JFactory::getDbo();
$db->setQuery('SELECT 1, 2 FROM #__table');
$results = $db->loadRowList();
$numrows=count($results);
if($numrows >0) {
foreach($results as $regexes) {
$document = str_replace($regexes[0],$regexes[1],$document);
}
return $document;
}
else {
$document = 'error with plugin';
}
JResponse::setBody($document);
return $document;
}
}
}
at the moment $data returns an array with a key 1 and value (string) of "" (blank/empty).
but not the data from the database I am expecting.
in simple terms I have {sometext} in my file and my database and it should return <p>my other text</p>
can you help?
thanks
Ok. Well looking at this deeper there is a couple of issues that jump out. The biggest being that you save getBody into a variable named $bob but then switch everywhere to using $document which is the object form above, not the content.
Also, you had a return $document hanging out in the middle of the code that prevented you from seeing that you were going to set $document as the new body. Probably should be more like below:
$bob=JResponse::getBody();
$db = &JFactory::getDbo();
$db->setQuery('SELECT 1, 2 FROM #__table');
$results = $db->loadRowList();
$numrows=count($results);
if($numrows >0) {
foreach($results as $regexes) {
$bob = str_replace($regexes[0],$regexes[1],$bob);
}
}
else {
$bob = 'error with plugin';
}
JResponse::setBody($bob);
return $document;
}
Original Thoughts:
Two thoughts to get you started. I'm not sure that this will actually fully answer the question, but should get you moving in the right direction.
First, you should not have to trigger the system plugin. They are system plugins, so the system will take care of that for you. If you wanted to use content plugins in your component (which you can definitely do!) then you would have to trigger them like your first set of code. In this case, don't bother with the entire dispatch section.
Second, your plugin looks set up to grab the body from the JDocument correctly, so that should work.
The likely issue is that the entire system plugin is just not being triggered. Make sure that it is installed and everything is named correctly. It has to be at plugins/system/myplugin/myplugin.php based on this name and make sure that the xml file with this also references myplugin as the plugin name. If not, the system won't find the class but likely won't throw an error. It will just skip it. This gives me trouble every time.
To do some checking just to make sure it gets called, I usually throw an echo or var_dump near the top of the file and just inside the function. Confirm that the function is at least getting called first and you should be most of the way to getting this to work.
I have a random number generator here, but I can't get it working above all WordPress comments. I get:
Fatal error: Cannot redeclare class Random in [mysite]/functions.php on line 148
Here is the function for the random number generator:
/**
* Generate random images for the forum games function
*/
function random_forum_games() {
class Random {
// random seed
private static $RSeed = 0;
// set seed
public static function seed($s = 0) {
self::$RSeed = abs(intval($s)) % 9999999 + 1;
self::num();
}
// generate random number
public static function num($min = 0, $max = 9999999) {
if (self::$RSeed == 0) self::seed(mt_rand());
self::$RSeed = (self::$RSeed * 125) % 2796203;
return self::$RSeed % ($max - $min + 1) + $min;
}
}
// set seed
Random::seed(42);
// echo 10 numbers between 1 and 10
for ($i = 0; $i < 1; $i++) {
echo Random::num(1, 10) . '<br />';
}
}
add_action( 'forum_games', 'random_forum_games' );
In order to call the function above every comment, in my comments template, I have:
<?php do_action ( 'forum_games' ); ?>
I know why what I am doing is wrong, but I am not really a "programmer". I came here for a little bit of simple help, whether it be a single line of code or a link to something that can tell me what to do without trying to teach me PHP. I do not have time to learn PHP, so please be kind. If there is not a simple solution, then you don't have to answer.
I don't mean to sound defensive, but I have been turned away by programmers before. Not everyone who needs to get something running has the time or skill to learn every single detail. You don't expect every person who prepares a meal for their family to learn how to hunt or to make pesticides, so please do not turn me away just because I cannot do PHP. If you want, just link me to something that isn't trying to teach me to code from scratch. I am doing as much of the work myself as I can, and I'm asking only for tidbits of support, so please don't be rude. Thank you.
You do not define a class inside a function. It should be defined OUTSIDE of the function, and then you can (if need be) INSTANTIATE it inside the function, e.g.
class rand {
...
}
function get_rand() {
$r = new rand();
}
or better yet, you would simply have a get_rand() method inside the class:
class rand() {
function get_rand() {
...
}
}
$r = new rand();
echo $r->get_rand();
it seems like you declared the function more than once. Maybe it is included more than once or you are calling the class more than once. Try moving the class out of the function and if it is in an include file, include it only once with include_once rather than include.
As for people not being friendly... some are, so what. Most are friendly, helpful... just make sure you give details about your problem (code + way to make it repeatable) and show you made an effort, you'll be fine :)
function KeepSamePage($text)
{
$sb_w = $oPdf->GetStringWidth($text);
$num_lines = explode("\n",$text);
$total = 0;
foreach($num_lines as $line)
{
$y = $oPdf->GetY();
$page_height = 11 * 25.4;
$this_width = $oPdf->GetStringWidth(strip_tags($line));
$extra_line = floor($this_width / $w);
$is_line = $this_width / ($w - 1);
$is_line = $this_width == 0 ? 1 + $extra_line : ceil($is_line) + $extra_line;
$total = $total + $is_line;
}
$sb_height = $total * 5;
if(($page_height - $y) < $sb_height){ $oPdf->AddPage(); }
}
KeepSamePage($signature_block);
I'm using FPDF and I'm creating a function to keep the signature page of a letter all on the same page. This checks to see if it would go to the next page and if soo, then it does an AddPage();
The issue I'm having is that when I don't have it in a function, it works perfectly, but when I put it within a function, I get errors when calling the methods in the class represented by $oPdf.
So, my question generally is this: Is it possible to have a regular function in PHP call a class method as I have below? If it is possible, what am I doing wrong?
ERROR GENERATED IS:
Fatal error: Call to a member function GetStringWidth() on a non-object in /home/jarodmo/public_html/cms/attorney_signature_block.php on line 18
Oh, and an explanation of my function just in case you're interested or someone else finds it.
Text has \n for new lines in it so the PDF will put the text of the signature block on the next line. Each new array element should be a new line, so I would need to multiply the number of lines by my line height, 5 in this case. (See $total * 5).
I check to see where we are on the page, find the difference between the page height and the Y position, then check that against the height of the signature block. If the signature block is bigger, then it wouldn't fit and I know we need a manual page break.
Also, because I do the explode with the \n to see the lines, I also have to check to make sure that none of the lines is still wider than the page otherwise it would word wrap and really be 2 lines (or more) where I was only counting it as 1 because it was just one array element. I know a signature block shouldn't have text wide enough to be on 2 lines, but I wrote this to be applicable for more than just signature blocks. I wanted to be able to call this function anywhere I wanted to make sure certain text stayed on the same page. Call the function, check the text I'm about to write to the PDF and move on knowing that the desired text would all be on the same page.
Thanks for all of the help and comments. SO is the best.
$oPdf
is not defined on your code. You need to define it, and maybe read PHP variable scope.
You are trying to access methods of the $oPdf object in your function, but your function has no idea what $oPdf is, thus, the error message.
you have to do something like this.
function KeepSamePage($text) {
$oPdf = new your_string_class();
$sb_w = $oPdf->GetStringWidth($text);
}
or
$oPdf = new your_string_class();
function KeepSamePage($text, $oPdf) {
$sb_w = $oPdf->GetStringWidth($text);
}
Try the following:
function KeepSamePage($text) {
global $oPdf;
…
}
The problem is, that the object is defined outside your function and you will have to allow your function to access it.
// Edit:
If you want to avoid global for whatever reason, you will have to pass your object to the function like this:
function KeepSamePage($text, $oPdf) {
…
// IMPORTANT! $oPdf has changed in this function, so you will have to give it back
return $oPdf;
}
You can call your function like this:
$oPdf = KeepSamePage($signature_block, $oPdf);
The advantage is, that you see in the main thread, that your function might has changed the object.
// Edit 2: I think, I was wrong on the edit1 in your case. As you pass the complete object to the function every change does apply to the object, so the changes will still be existant without giving back the result. If this was a variable that was defined in the main thread, you would have to give back the new value:
$a = 1;
function result1($a) {
++$a;
}
function result2($a) {
return ++$a;
}
echo $a."\n"; // 1
result1($a);
echo $a."\n"; // 1
$a = result2($a);
echo $a."\n"; // 2
I just installed a fresh copy of Kohana 3.2, built my database, wrote my first model, and tried testing it. Everything works fine except the model's "save" method is being executed twice--I end up with two new entries in the database instead of one. The problem only occurs when I use the "find" code shown below.
Why would the model's save get executed twice, once as expected and once because of the find?
Here's the code:
class Controller_Welcome extends Controller {
public function action_index()
{
$rating = ORM::factory('rating');
$rating->user_id = 1;
$rating->userlevel_id = 3;
$rating->category_id = 1;
$rating->page_id = 1;
$rating->rating = 4;
$rating->comments = 'This one is a real killer';
$rating->ratingstatus_id = 1;
$rating->save();
$found = ORM::factory('rating')
->where('id', '=', 1)
->find();
$this->response->body($found->comments); // Test to check for found data
}
} // End Welcome
Thanks in advance!
There are two issues that were causing my problem:
I didn't have a favicon.ico on my server. Many browsers request one, and all URLs that aren't actual files or directories get redirected to the index page. Every time I loaded the page, the browser would request a missing favicon and get redirected to my index page--two requests. After looking at my logs, this page was what tipped me off: http://forum.kohanaframework.org/discussion/7447/error-kohana_request_exception/p1
After I added a favicon, I still saw the double request behavior occasionally. It turns out it was a behavior of Google Chrome--Chrome prefetches pages, so each time I changed the content, Chrome would prefetch and cache the page (adding a request).
After adding a favicon and when using a browser besides Chrome, everything behaves as expected.
$rating = ORM::factory('rating');
This line represents nothing.
If you want to create new record you should use create() instead save().
$rating = new Model_Rating;
$rating->user_id = 1;
$rating->userlevel_id = 3;
$rating->category_id = 1;
$rating->page_id = 1;
$rating->rating = 4;
$rating->comments = 'This one is a real killer';
$rating->ratingstatus_id = 1;
$rating->create();
If you want to load single rating object with given id:
$found = ORM::factory('rating', 1);