Mediawiki Call to undefined method SpecialPage::addPage() - mediawiki-extensions

I need to use an older Mediawiki extension on our site, that isn't maintained anymore. When I activate the extension I get the following Error:
'Call to undefined method SpecialPage::addPage()'
As far as I found out, this is due to the fact, that in Mediawiki since version 1.25 they changed the way how new Special pages are created and registered. I could not find examples that showed how to fix the code from an older extension so that it could work in the actual version of MW.
Here is the relevant code of the extension where the SpecialPage is created and registered.
require_once( './includes/specialpage/SpecialPage.php' );
$wgSpecialPages['Events'] = new SpecialPage ( 'Events' );
$wgExtensionFunctions[] = 'efEventsExtn';
$wgExtensionCredits['specialpage'][] = array(
'name' => 'Events',
'author' => 'Barrylb',
'description' => 'Adds [[Special:Events|a special page]] for viewing events',
'url' => 'http://www.mediawiki.org/wiki/Extension:Calendar_%28Barrylb%29'
);
function efEventsExtn() {
$wgamMessages = array();
SpecialPage::addPage( new EventsExtn() );
$wgamMessages = array( 'events' => 'Events' , 'events-header' => '');
}
class EventsExtn extends IncludableSpecialPage {
function EventsExtn() {
SpecialPage::SpecialPage( 'Events', '', true, false, 'default', true );
}
... (The rest of the code seems to work properly)
Maybe someone known how to fix this?

Just $wgSpecialPages should be enough:
$wgSpecialPages['Events'] = 'EventsExtn';
I would mistrust an extension that uses a function that was deprecated in MediaWiki 1.7, though.

Related

Content type is not saved when altering the node add form

Here, I have alter the add content type form as follows:
function hc_listings_form_alter(&$form, &$form_state, $form_id)
{
// print_r($form_id);
if($form_id =='home_care_popular_search_region_node_form'){
dpm($form,'form');
$selected_states=hc_listings_load_agecare_regions();
// dpm($selected_states,'selected');
reset($selected_states);
$first_state = key($selected_states);
// dpm($first_state,'$first_state');
$form['field_popular_state']=array(
'#type' => 'select',
'#default_value' => array_shift($selected_states),
'#title' => t('Popular State'),
'#description' => t('Home Care Popular State'),
'#options'=>hc_listings_load_agecare_regions(),
'#ajax'=>array(
'callback'=> 'hc_popular_region_form_ajax',
'wrapper'=> 'regions_list',
'event'=>'change',
'method'=>'replace',
),
'#required' => TRUE,
);
$form['field_popular_region']=array(
'#type' => 'container',
'#tree'=>TRUE,
'#prefix'=>'<div id="regions_list">',
'#suffix'=>'</div>'
);
$form['field_popular_region']['list']=array(
'#type' => 'checkboxes',
'#title' => t('Popular Search Regions'),
'#description' => t('Home Care Popular Search Regions'),
'#options'=>get_popular_regions($first_state),
'#required' => TRUE,
);
}
}
And the ajax Callback function is as follows:
function hc_popular_region_form_ajax($form, &$form_state){
if(isset($form_state['values']['field_popular_state'])){
$state=$form_state['values']['field_popular_state'];
hc_my_log($state);
$form['field_popular_region']['list']=array(
'#type'=>'checkboxes',
'#title'=>'Popular Search Regions',
'#description'=>'Home Care Popular Search Regions',
'#options'=>get_popular_regions($state)
);
hc_my_log($form['field_popular_region']['list']);
$form['field_popular_region']['list']=form_process_checkboxes($form['field_popular_region']['list']);
}
// $form_state['rebuild'] = true;
return $form['field_popular_region'];
}
This works but when the ajax callback is called it will execute the dpm($form,'form') (line:5) too. What is the reason for this?
And after that when I am submitting the form by clicking the default Save button in the node add form both popular regions and popular states values are not saved. What will be the cause of that? Should I have to alter the submission of the node too ?
Here ,I have altered the form fields in a wrong way so in the form submission it alerts me with errors saying that the form structure has been changed in my altering.
The error is that it is not directly targetting the specific form field..so it should be corrected as follows:
if($form_id =='home_care_popular_search_regions_node_form'){
$selected_states=hc_get_states();
reset($selected_states);
$first_state = key($selected_states);
dpm($first_state,'$first_state');
$state= (isset($form_state['values']['field_popular_state']['und'][0]['tid']))?$form_state['values']['field_popular_state']['und'][0]['tid']:$first_state;
//popular states field altering
$form['field_popular_state']['und']['#default_value']=$selected_states[$first_state];
$form['field_popular_state']['und']['#options']=$selected_states;
$form['field_popular_state']['und']['#ajax']['callback']='hc_popular_region_form_ajax';
$form['field_popular_state']['und']['#ajax']['wrapper']='regions_list';
$form['field_popular_state']['und']['#ajax']['method']='replace';
$form['field_popular_state']['und']['#ajax']['event']='change';
//popular regions field altering
$form['field_popular_region']['und']['#prefix']='<div id="regions_list">';
$form['field_popular_region']['und']['#suffix']='</div>';
$form['field_popular_region']['und']['#options']=hc_get_popular_regions($state);
}
Ajax callback is as follows:
function hc_popular_region_form_ajax($form, &$form_state){
return $form['field_popular_region'];
}
Note: the method hc_listings_load_agecare_regions() has been changed to hc_get_states()

Is it possible to customise drupal node reference and pass your search and a argument from another field

I'm trying to create a bespoke form in drupal, with a node reference field.
I'd like to add a little extra functionality to the node reference auto complete. I've created a view, that contains an argument. I'd like to be able to pass that argument from a drop down as well as the typed text into the autocomplete script.
Does anyone know how I'd start this off.
/* FIELD 1 - the drop down */
$sql = "SELECT nid, title FROM node where type='resourcetype' AND status =1 order by title
";
$result = db_query($sql);
$counter = 0 ;
$options = array();
while ($data = db_fetch_array($result)) {
// krumo ($data);
$options[$data[nid] ] = $data[title] ;
if ($counter ==0 ) {$df = $data[nid]; }
$counter ++;
}
/* FIELD 2 - the node reference field */
$form['sor']['type'] = array(
'#type' => 'select',
'#title' => t('Resource type'),
'#required' =>TRUE,
'#options' => $options,
) ;
$form['sor']['field_asor_sors'] = array(
'#type' => 'textfield',
'#title' => t('Add a SOR item to this job'),
'#autocomplete_path' => 'nodereference/autocomplete/field_asor_sors',
'#element_validate' => array('myelement_validate_is_valid_noderef'),
'#required' =>TRUE,
);
Many Thanks
Matt
AFAIK there is no easy way to do this.
I wanted to do something similar a while ago (using different arguments based on node context), but refrained from doing it, since it would've needed some significant changes of the autocomplete callback logic. You'd need to change several nodereference functions to add support for passing an argument to the initial callback nodereference_autocomplete(), passing it on from there to _nodereference_potential_references(), and finally to _nodereference_potential_references_views(), while ensuring that the changes don't break anything else.
If you want to try nonetheless, you should take a look at the patches in this thread, as they also want to do something like that and might contain some useful hints/examples.
A potentially easier alternative might be to exchange the #autocomplete_path callback of the nodereference field with your own custom version that would generate the result, while adding js logic to your dropdown to add an additional argument to that path when the selection changes.
If you go into the nodereference field configuration form, and scroll all the way to the bottom, there's a fieldset (which may be collapsed) that is titled 'Advanced - Nodes that can be referenced (View)'. You can use this to select a view and have that view be the source of the nodereference choices without writing any new code.

Set Redux sorter field option values programatically

I'm working on a section sorter plugin, for that I used Redux to set a simple options page with only the sorter field. The thing is, I can't put the enabled values programatically, I have tried several ways and nothing seems to work.
I am using AJAX to get the ids of all section tags in homepage, then, I send the sections' ids to a function in the options file (Redux options file, sample-config.php, or in my case sorting-sections-options.php , like this:
This is my JS/JQ/AJAX code:
jQuery(document).ready(function($){
var sections_ids = {action: 'save_sections_ids'};
$.get(window.location.protocol + "//" + window.location.host + "/futbol-americano", function(data) {
var sections_elements = $(data).find("section");
sections_elements.each(function(){
var section_id = $(this).attr("id");
sections_ids[section_id] = section_id;
console.log(section_id);
});
pass_ids_to_server(sections_ids);
});
function pass_ids_to_server(sections_ids){
$.ajax({
url : sorting_sections.ajax_url,
type : 'post',
data : sections_ids,
success : function( response ) {
alert(response);
}
});
}
});
This is the function that receives the data from ajax:
This is the form is has currently, but I have tried looping the $_POST variable and returning an array to place inside the 'enabled' => $array and several other ways, so I though the asinchronous call could be doing that the field load before the function and decided to store the data in user meta.
add_action( 'wp_ajax_save_sections_ids', 'save_sections_ids_sorting_sections' );
function save_sections_ids_sorting_sections() {
$user_id = get_current_user_id();
update_user_meta($user_id, "set-sections", $_POST);
}
The AJAX call works, and the function that receives the data works as well. The data stores in the user_meta table in database. But when I do this:
$user_id = get_current_user_id();
$get_sections_array = get_user_meta($user_id, "set-sections", true);
//Returns false but if var_dumped inside the save_sections_ids_sorting_sections() function, it shows the array correctly in an alert box (from succes on ajax call).
$sorter_field = array(
'section_id' => 'basic',
'id' => 'opt-homepage-layout-3',
'type' => 'sorter',
'title' => 'Este es el titulo',
'desc' => 'this is the description',
'compiler' => 'true',
'options' => array(
'disabled' => array(
),
'enabled' => $get_sections_array;
));
Redux::setField($opt_name, $sorter_field );
//The Redux::setField($opt_name, $sorter_field ); works if I define $sorter_field manually before the instance.
I get the following error message in the options page:
Warning: array_merge(): Argument #2 is not an array in C:\xampp\htdocs\futbol-americano\wp-content\plugins\sorting-sections\ReduxFramework\ReduxCore\inc\fields\sorter\field_sorter.php on line 81
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\futbol-americano\wp-content\plugins\sorting-sections\ReduxFramework\ReduxCore\inc\fields\sorter\field_sorter.php on line 103
I hope someone can help with this.
Thanks in advance.

wpdb Update function getting “Undefined Index” error for each table column

I'm developing a plugin that lets me add and delete custom table records. Adding and deleting records works fine.
I also want to be able to update the records. This is where I cannot figure out what I'm doing wrong.
Here is my update code if anyone can point me in the right direction (I'm currently focused on the "update selected record" script:
function url_update() {
global $wpdb;
$id = $_GET["id"];
$launchname=$_POST["launchname"];
$url1 = $_POST["url1"];
$url2 = $_POST["url2"];
$urluser = $_POST["urluser"];
$urlpwd = $_POST["urlpwd"];
$wpfirstname = $_POST["wpfirstname"];
$wplastname = $_POST["wplastname"];
$wpemail = $_POST["wpemail"];
$activated = $_POST["activated"];
//update selected record
if(isset($_POST['update'])){
$wpdb->update('launcher',
array(
'id' => $id,
'launchname' => $launchname,
'url1' => $url1,
'url2' => $url2,
'urluser' => $urluser,
'urlpwd' => $urlpwd,
'wpfirstname' => $wpfirstname,
'wplastname' => $wplastname,
'wpemail' => $wpemail,
'activated' => $activated
),
array( 'ID' => $id ), //this line fixed the issue
array('%d','%s','%s','%s','%s','%s','%s','%s','%s','%s'));
}
//delete
else if(isset($_POST['delete'])){
$wpdb->query($wpdb->prepare(
"DELETE FROM wp_tincan_launcher WHERE id = %d",$id
));
}
else{
//selecting row to update
$selected_record = $wpdb->get_results($wpdb->prepare(
"SELECT id,launchname,url1,url2,urluser,urlpwd,wpfirstname,
wplastname,wpemail,activated from launcher where id=%d",$id
));
foreach ( $selected_record as $s ){
$launchname=$s->launchname;
$url1=$s->url1;
$url2=$s->url2;
$urluser=$s->urluser;
$urlpwd=$s->urlpwd;
$wpfirstname=$s->wpfirstname;
$wplastname=$s->wplastname;
$wpemail=$s->wpemail;
$activated=$s->activated;
}
}
I think my code is correct, however, I would really appreciate some feedback that directly addresses my code.
EDIT: Thanks to Pekka for pointing out that I did not identify the error results.
The Error I'm getting from WP is "Notice: Undefined index: each column in the DB."
Best Regards
I resolved it myself by changing my update query to include a new line as follows: array( 'ID' => $id ), before the types line.
None of the links I was led to, not any of the generic advice I was provided was of any help what-so-ever.
I've edited the original code to reflect the complete working code.

PayPal in Symfony2 [closed]

I'm trying to use JMSPaymentCoreBundle with JMSPaymentPaypalBundle and I can't find a clear example anywhere on how to do it.
I've done all steps specified in the documentation and I'm not able to get it working. Can anybody help me please?
The default way to create a payment instruction is through the jms_choose_payment_method form:
$form = $this->getFormFactory()->create('jms_choose_payment_method', null, array(
'amount' => 12.99,
'currency' => 'EUR',
'default_method' => 'payment_paypal', // Optional
'predefined_data' => array(
'paypal_express_checkout' => array(
'return_url' => $this->get('router')->generate('payment_complete', array(
'number' => $order->getOrderNumber(),
), true),
'cancel_url' => $this->get('router')->generate('payment_cancel', array(
'number' => $order->getOrderNumber(),
), true)
),
),
));
You can also create a payment instruction manually:
use JMS\Payment\CoreBundle\Entity\ExtendedData;
use JMS\Payment\CoreBundle\Entity\Payment;
use JMS\Payment\CoreBundle\PluginController\Result;
use JMS\Payment\CoreBundle\Plugin\Exception\ActionRequiredException;
use JMS\Payment\CoreBundle\Plugin\Exception\Action\VisitUrl;
use JMS\Payment\CoreBundle\Entity\PaymentInstruction;
$extendedData = new ExtendedData();
$extendedData->set('return_url', $this->get('router')->generate('payment_complete', array(
'number' => $order->getOrderNumber(),
), true));
$extendedData->set('cancel_url', $this->get('router')->generate('payment_cancel', array(
'number' => $order->getOrderNumber(),
), true));
$instruction = new PaymentInstruction((float)$order->getCharge() > 0 ? $order->getCharge() : $order->getAmount(), 'EUR', 'paypal_express_checkout', $extendedData);
$this->get('payment.plugin_controller')->createPaymentInstruction($instruction);
$order->setPaymentInstruction($instruction);
$em = $this->get('doctrine.orm.entity_manager');
$em->persist($order);
$em->flush();
My payment_complete route looks like:
public function completeAction(Booking $order)
{
$instruction = $order->getPaymentInstruction();
if (($instruction->getAmount() - $instruction->getDepositedAmount()) > 0) {
if (null === $pendingTransaction = $instruction->getPendingTransaction()) {
$payment = $this->get('payment.plugin_controller')->createPayment($instruction->getId(), $instruction->getAmount() - $instruction->getDepositedAmount());
} else {
$payment = $pendingTransaction->getPayment();
}
$result = $this->get('payment.plugin_controller')->approveAndDeposit($payment->getId(), $payment->getTargetAmount());
if (Result::STATUS_PENDING === $result->getStatus()) {
$ex = $result->getPluginException();
if ($ex instanceof ActionRequiredException) {
$action = $ex->getAction();
if ($action instanceof VisitUrl) {
return new RedirectResponse($action->getUrl());
}
throw $ex;
}
} else if (Result::STATUS_SUCCESS !== $result->getStatus()) {
throw new \RuntimeException('Transaction was not successful: '.$result->getReasonCode());
}
}
$order->setTransactionAmount((float)$order->getAmount());
$creditPurchased = (float)$order->getCharge() > (float)$order->getAmount() ? (float)$order->getCharge() - (float)$order->getAmount() : 0;
$em->persist($order);
$em->flush();
I've got it running going through http://jmsyst.com/bundles/JMSPaymentCoreBundle/master/usage
Payum bundle supports jms payments via the bridge. The links describes how to get started.
Usage of the bundle gives you several advantages:
Secured capture action.
Have credit card form, can ask user for credit card
Ability to easy setup IPN. Notify action is also secured.
Built-in support of all omnipay gateways (25 +), jms plugins (+ 10) and payum native libs.
Payum paypal lib supports recurring payment and digital goods out of the box.
Storages integrated into payment process so you do not have worry about data that might be lost.
Domain friendly. Indeed Payum provide some models but it does not restrict you to use them.
It already supports PSR-0 logger. In dev it logs executed payum actions, to easy debug (Visit symfony profile logs tab).
It is possible setup several payments (one paypal account for EU and one for US for example)
Extremely customizable. Add your custom payum actions, or extensions, or storages.
There is a symfony sandbox (code|web) to help you to start.
P.S. It is not the full list of features.

Resources