I've built a Wordpress plugin, and now I want to add support for Visual Composer but I can't get it to work. I've read a lot of articles about how to use vc_map, found pages on github with examples, and it seems like I do everything like described in these articles. However my shortcodes still don't show up in the VC editor.
My shortcode (it works perfectly as a shortcode, [mappy id="123"] will show the map with the ID of 123)
add_shortcode('mappy', 'mappy_shortcode');
function mappy_shortcode($atts) {
// Attribute defaults
extract(shortcode_atts(array(
'id' => null,
), $atts));
// Check if id is set, and the given post is a mappy_map
if(!isset($atts['id'])) {
return '';
}
$post = get_post(intval($atts['id']));
if(!isset($post)) {
return;
}
if($post->post_type != 'mappy_map') {
return;
}
return $post->post_content;
}
And the code I've tried:
/**
* Visual Composer Support
*/
if(defined('WPB_VC_VERSION')) {
add_action('vc_before_init', 'mappy_vc_support');
}
function mappy_vc_support() {
vc_map(
array(
'base' => 'mappy',
'description' => __('Display a Mappy map.', 'mappy'),
'category' => 'Mappy',
'icon' => plugin_dir_url(__FILE__) . 'img/vc_map_32.png',
'class' => '',
'weight' => 100,
'params' => array(
array(
'type' => 'dropdown',
'class' => '',
'heading' => __('Térkép', 'mappy'),
'param_name' => 'id',
'value' => mappy_map_list(),
'description' => __('Térkép', 'mappy'),
'holder' => 'div'
)
)
)
);
}
/**
* Helper function to get all mappy_map posts
*/
function mappy_map_list() {
$list = array();
$posts = get_posts(array('post_type' => 'mappy_map'));
foreach($posts as $post) {
$list[$post->post_title] = $post->ID;
}
return $list;
}
I've also tried to hook mappy_vc_support into init and admin_init, with no luck.
Also note that the function vc_map itself is being called, and returns 1.
What could be the problem here?
Related
I would like to create a plugin, which should add a button for each post in the backend in the post overview section so that I can click on it and run a database operation referencing the post title. Elementor for example does that (as shown in the image).
Unfortunately, I don't know where to find or search for the area to create something for the backend post overview.
The actual aim was to create a table entry for each post entry. I tried to accomplish this with the use of hooks, but I couldn't prevent it from firing twice or when updating the post. Other than that, it worked as expected.
add_action('save_post', 'add_workshop_poll_nc');
function add_workshop_poll_nc( $post_id ) {
global $wpdb;
//Check to see if user posted first time
if ( !(wp_is_post_revision($post_id)) || wp_is_post_autosave($post_id)){
return;
}
if(get_post_type(4)){
$table_name = 'oc_polls_polls';
$poll_title = get_the_title($post_id);
$wpdb->insert(
$table_name,
array(
'type' => 'datePoll',
'title' => $poll_title,
'description' => '',
'owner' => 'admin',
'created' => 1602851840,
'expire' => 1604151026,
'deleted' => 0,
'access' => 'hidden',
'anonymous' => 1,
'full_anonymous' => 0,
'allow_maybe' => 1,
'options' => '',
'settings' => '',
'vote_limit' => 0,
'show_results' => 'expired',
'admin_access' => 1,
'important' => 0));
}
remove_action('save_post', 'add_workshop_poll_nc'); //to prevent multiple database entries of same post
}
That is the reason I would like to do use a manual trigger such as a link/button. These links/buttons should only be visible to a custom post type (workshop).
Can someone give me a hint, how to approach this problem or help me solve it?
I am new to WordPress/PHP so please be indulgent :)
EDIT:
Thanks to Chris Haas I managed to get it work with the following Code:
add_filter( 'post_row_actions', 'termin_add_action_button', 10, 2 );
function termin_add_action_button($actions, $post){
if(get_post_type() === 'workshop'){
$url = add_query_arg(
array(
'post_id' => $post->ID,
'my_action' => 'custom_termin_post',
)
);
$actions['termin'] = 'Terminierung anlegen';
}
return $actions;
}
add_action( 'admin_init', 'custom_termin_function' );
function custom_termin_function(){
if ( isset( $_REQUEST['my_action'] ) &&
'custom_termin_post' == $_REQUEST['my_action'] ) {
global $wpdb;
$table_name = 'oc_polls_polls';
$poll_title = get_the_title($_REQUEST['post_id']);
$wpdb->insert(
$table_name,
array(
'type' => 'datePoll',
'title' => $poll_title,
'description' => '',
'owner' => 'admin',
'created' => 1602851840,
'expire' => 1604151026,
'deleted' => 0,
'access' => 'hidden',
'anonymous' => 1,
'full_anonymous' => 0,
'allow_maybe' => 1,
'options' => '',
'settings' => '',
'vote_limit' => 0,
'show_results' => 'expired',
'admin_access' => 1,
'important' => 0
)
);
exit;
}
}
I have one problem left. If I click on the button, currently it opens a new tab and performs the action. I would rather have the operation to be invisible. Is this possible? If I don't use target="_blank" than I am being redirected to a blank white page.
Is there a better solution? :)
SOLUTION:
Thanks to Chris Haas I managed to get it work with the following Code:
/**
* Action to create a workshop poll in Nextcloud
*/
add_filter( 'post_row_actions', 'termin_add_action_button', 10, 2 );
function termin_add_action_button($actions, $post){
if(get_post_type() === 'workshop'){
$url = add_query_arg(
array(
'post_id' => $post->ID,
'my_action' => 'custom_termin_post',
)
);
$actions['termin_add'] = 'Terminierung anlegen';
}
return $actions;
}
add_action( 'admin_init', 'custom_termin_add_function' );
function custom_termin_add_function(){
if ( isset( $_REQUEST['my_action'] ) && 'custom_termin_post' == $_REQUEST['my_action']) {
global $wpdb;
$poll_table_name = 'oc_polls_polls'; //table name of polls
$wordpress_table_name = 'wordpress_polls'; //storage of primary keys of post id and poll id
$poll_title = get_the_title($_REQUEST['post_id']); //poll title
$curTimestamp = current_datetime(); //current time stamp
$time_created = $curTimestamp->getTimestamp()+$curTimestamp->getOffset(); //creation date
$time_expire = $time_created + 1814400; //expire date 3 weeks after creation date
$poll_id; //poll id
$wordpress_polls = $wpdb->get_results("SELECT wordpress_id, poll_id FROM ".$wordpress_table_name." WHERE wordpress_id = ".$_REQUEST['post_id']);
$wordpress_polls_rows = $wpdb->num_rows;
if($wordpress_polls_rows === NULL || $wordpress_polls_rows === 0){
//create poll
$wpdb->insert(
$poll_table_name,
array(
'type' => 'datePoll',
'title' => $poll_title,
'description' => '',
'owner' => 'admin',
'created' => $time_created,
'expire' => $time_expire,
'deleted' => 0,
'access' => 'hidden',
'anonymous' => 1,
'full_anonymous' => 0,
'allow_maybe' => 1,
'options' => '',
'settings' => '',
'vote_limit' => 0,
'show_results' => 'expired',
'admin_access' => 1,
'important' => 0
)
);
$poll_id = $wpdb->insert_id; //save ID of poll
//create poll and wordpress relation
$wpdb->insert(
$wordpress_table_name,
array(
'wordpress_id' => $_REQUEST['post_id'],
'poll_id' => $poll_id
)
);
echo "<script>window.close();</script>";
exit;
} else {
echo "<script>window.close();</script>";
exit;
}
}
}
If there is a better or optimized solution, please let me know :)
I am wanting to add a link to the Wordpress admin bar that will eventually purge all cache. At the moment I am trying to add the link to the admin bar but seem to be having problems.
I have followed a few methods I had found on Google, but for some reason I couldn't get them to work. (I don't know if this is due to the examples being outdated with the version of Wordpress?)
Here is what I am using so far:
function time_to_purge($wp_admin_bar) {
$args = array(
'id' => 'DaylesPurge',
'title' => 'Purge Cache',
'href' => '#',
'meta' => array(
'class' => 'DaylesPurge'
)
);
$wp_admin_bar->add_node($args);
}
add_action('admin_bar_menu', 'time_to_purge', 50);
function PurgeConfirmation() {
document.getElementById("PurgeConfirmation").innerHTML = "Are you sure you
wish to purge the cash?";
}
[EDIT]
Never-mind, this works perfectly. It was a matter of a simple spelling mistake in my code that was preventing it from displaying.
function time_to_purge($wp_admin_bar) {
$args = array(
'id' => 'DaylesPurge',
'title' => 'Purge Cache',
'href' => '#',
'meta' => array(
'class' => 'DaylesPurge'
)
);
$wp_admin_bar->add_node($args);
}
add_action('admin_bar_menu', 'time_to_purge', 50);
function PurgeConfirmation() {
document.getElementById("PurgeConfirmation").innerHTML = "Are you sure you
wish to purge the cash?";
}
I have simple Yii cgridview code with pagination. Pagination is working fine but in the last page I have faced one issue.
For example, If I have 13 records in DB table, and set pagination for 10 pages per page then for first page It will show "1 - 10 of 13 results" but when I clicked on 2nd page link then It will show "4 - 13 of 13" instead of "11 - 13 of 13".
Here is my code.
1) Controller :
function actiontransactionHistory(){
$creditTransactionObj = new CreditTransaction();
$this->render('history',array(
'creditTransactionObj'=>$creditTransactionObj,
));
}
2) Model :
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id,true);
$criteria->compare('fkasmtGroupId',$this->fkasmtGroupId);
$criteria->compare('fkgroupSurveyUserId',$this->fkgroupSurveyUserId,true);
$criteria->compare('fkasmtId',$this->fkasmtId);
$criteria->compare('transaction_type',$this->transaction_type);
$criteria->compare('credit_type',$this->credit_type,true);
$criteria->compare('credit_qty',$this->credit_qty);
$criteria->compare('transaction_date',$this->transaction_date,true);
$criteria->compare('isDelete',$this->isDelete);
$criteria->compare('status',$this->status);
$criteria->compare('created_at',$this->created_at,true);
$criteria->compare('modified_at',$this->modified_at,true);
$sort = array(
"defaultOrder" => "transaction_date DESC",
);
return new CActiveDataProvider($this, array(
"criteria"=>$criteria,
"sort" => $sort,
));
}
3) View:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'history-grid',
'dataProvider' => $creditTransactionObj->search(),
'loadingCssClass' => '',
'enableSorting' => true,
'itemsCssClass' => 'my-teams',
'summaryText' => "Displaying {start} - {end} of {count} results.",
"emptyText" => "There is no transaction history available.",
'columns' => array(
array('name' => 'transaction_date', 'header' => 'Date', 'type' => 'raw', 'value' => 'date("d-M-Y",strtotime($data->transaction_date))', 'htmlOptions' => array('class' => '')),
array('name' => 'credit_qty', 'header' => '# of Credits', 'sortable'=>false, 'type' => 'raw', 'value' => '($data->transaction_type == 1) ? - $data->credit_qty : $data->credit_qty', 'htmlOptions' => array('class' => '')),
array('name' => 'credit_type', 'header' => 'Type', 'type' => 'raw', 'value' => '$data->credit_type', 'htmlOptions' => array('class' => '')),
array('name' => 'transaction_type', 'header' => 'Activity', 'type' => 'raw', 'value' => '($data->transaction_type == 0) ? "Purchased" : (($data->transaction_type == 1) ? "Spent" : "Refunded")', 'htmlOptions' => array('class' => '')),
array('name' => 'fkasmtGroupId', 'header' => 'Group Name', 'type' => 'raw', 'value' => array($this,'getGroupName'), 'htmlOptions' => array('width' => '35%')),
)
));
?>
I have also attached both pages screenshot.
Any help will be appreciate. Thanks in advance !
After spending lots of hours finally I found the solution for this issue.
Actually the problem was in fetchData() function which is used in
yii/framework/web/CActiveDataProvider.php framework class file.
In fetchData() method, limit was not calculated properly for the last page pagination. so I have made changes to calculate correct limit.
Old Code:
protected function fetchData()
{
$criteria=clone $this->getCriteria();
if(($pagination=$this->getPagination())!==false)
{
$pagination->setItemCount($this->getTotalItemCount());
$pagination->applyLimit($criteria);
}
$baseCriteria=$this->model->getDbCriteria(false);
if(($sort=$this->getSort())!==false)
{
// set model criteria so that CSort can use its table alias setting
if($baseCriteria!==null)
{
$c=clone $baseCriteria;
$c->mergeWith($criteria);
$this->model->setDbCriteria($c);
}
else
$this->model->setDbCriteria($criteria);
$sort->applyOrder($criteria);
}
$this->model->setDbCriteria($baseCriteria!==null ? clone $baseCriteria : null);
$data=$this->model->findAll($criteria);
$this->model->setDbCriteria($baseCriteria); // restore original criteria
return $data;
}
New Code:
protected function fetchData()
{
$criteria=clone $this->getCriteria();
if(($pagination=$this->getPagination())!==false)
{
$pagination->setItemCount($this->getTotalItemCount());
$pagination->applyLimit($criteria);
// update limit to the correct value for the last page
$limit=$pagination->getLimit();
$offset=$pagination->getOffset();
if ( $offset+$limit > $pagination->getItemCount() )
$criteria->limit = $pagination->getItemCount() - $offset;
}
$baseCriteria=$this->model->getDbCriteria(false);
if(($sort=$this->getSort())!==false)
{
// set model criteria so that CSort can use its table alias setting
if($baseCriteria!==null)
{
$c=clone $baseCriteria;
$c->mergeWith($criteria);
$this->model->setDbCriteria($c);
}
else
$this->model->setDbCriteria($criteria);
$sort->applyOrder($criteria);
}
$this->model->setDbCriteria($baseCriteria!==null ? clone $baseCriteria : null);
$data=$this->model->findAll($criteria);
$this->model->setDbCriteria($baseCriteria); // restore original criteria
return $data;
}
But remember, never update a core class file of framework. so I just extend this method in my Model file and write below code.
Final Code In My Model file without change in framework file:
class CustomActiveDataProvider extends CActiveDataProvider
{
/**
* Fetches the data from the persistent data storage.
* #return array list of data items
*/
protected function fetchData()
{
$criteria=clone $this->getCriteria();
if(($pagination=$this->getPagination())!==false)
{
$pagination->setItemCount($this->getTotalItemCount());
$pagination->applyLimit($criteria);
// update limit to the correct value for the last page
$limit=$pagination->getLimit();
$offset=$pagination->getOffset();
if ( $offset+$limit > $pagination->getItemCount() )
$criteria->limit = $pagination->getItemCount() - $offset;
}
$baseCriteria=$this->model->getDbCriteria(false);
if(($sort=$this->getSort())!==false)
{
// set model criteria so that CSort can use its table alias setting
if($baseCriteria!==null)
{
$c=clone $baseCriteria;
$c->mergeWith($criteria);
$this->model->setDbCriteria($c);
}
else
$this->model->setDbCriteria($criteria);
$sort->applyOrder($criteria);
}
$this->model->setDbCriteria($baseCriteria!==null ? clone $baseCriteria : null);
$data=$this->model->findAll($criteria);
$this->model->setDbCriteria($baseCriteria); // restore original criteria
return $data;
}
}
// Used this custome active data provider as shown in below.
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id,true);
$criteria->compare('isDelete',$this->isDelete);
$criteria->compare('status',$this->status);
$criteria->compare('created_at',$this->created_at,true);
$criteria->compare('modified_at',$this->modified_at,true);
$sort = array(
"defaultOrder" => "transaction_date DESC",
);
return new CustomActiveDataProvider($this, array(
"criteria"=>$criteria,
"sort" => $sort,
"pagination" => array('pageSize' => (isset($_REQUEST['pageSize'])?$_REQUEST['pageSize']:10))
));
}
After this change, Last page pagination works completely fine.
Thanks!
I need some data added default in the editor.
Like I want a template to get loaded in editor when I click on edit template option..
Can anyone suggest me some tip??
Here you can see how it can be done
$dataa= $this->getTemplate1();
$fieldset->addField('content', 'editor', array(
'name' => 'content',
'label' => Mage::helper('abandonedcart')->__('Content'),
'title' => Mage::helper('abandonedcart')->__('Content'),
'style' => 'width:700px; height:500px;',
'wysiwyg' => true,
'required' => true,
'state' => 'html',
'config' => $wysiwygConfig,
'value'=> $dataa,
));
if (Mage::getSingleton('adminhtml/session')->getAbandonedcartData()) {
$form->addValues(Mage::getSingleton('adminhtml/session')->getAbandonedcartData());
Mage::getSingleton('adminhtml/session')->setAbandonedcartData(null);
} elseif (Mage::registry('abandonedcart_data')) {
$form->addValues(Mage::registry('abandonedcart_data')->getData());
}
return parent::_prepareForm();
}
and calling a function to have data
public function getTemplate1() {
$emailTemplate = Mage::getModel('core/email_template')->loadDefault('abandonedcart_abandonedcart_group_email_template');
$emailTemplate['template_text'];;
$template_id = Mage::getStoreConfig('abandonedcart/abandonedcart_group/email_template');
$emailTemplate = Mage::getModel('core/email_template')->loadDefault($template_id);
return $processedTemplate = $emailTemplate->getProcessedTemplate();
}
I have a content type (budget), it is a custom content type
function budget_node_info() {
return array(
'budget' => array(
'base' => 'budget',
'name' => t('Budget'),
'description' => t('Represents individual budget.'),
'title_label' => t('Budget Name'),
'locked' => TRUE
)
);
}
also I have the form function
function budget_form($node, $form_state) {
drupal_add_library('system', 'ui.tabs');
drupal_add_library('budget', 'highcharts');
drupal_add_js(drupal_get_path('module', 'budget') . '/js/budget_base.js');
drupal_add_js(drupal_get_path('module', 'budget') . '/js/' . $node->type . '.js');
$form = node_content_form($node, $form_state);
$config = variable_get($node->type);
I want to show the edit form on the node view page (I want to show form from node/[nid]/edit to node/[nid])?
I tried next:
function budget_node_view($node, $view_mode, $langcode){
$node->content['edit-form'] = array(
'#markup' => render(drupal_get_form('budget_form', $node)),
'#weight' => 10,
);
}
also I tried
function budget_node_view($node, $view_mode, $langcode){
$node->content['edit-form'] = array(
'#markup' => render(budget_form($node, array())),
'#weight' => 10,
);
}
2nd version show form but without any js or css loaded.
What am I doing wrong?
I used function node_page_edit($node) and seems like it works
function wp_budget_node_view($node, $view_mode, $langcode){
module_load_include('inc', 'node', 'node.pages');
$node->content['edit-form'] = array(
'#markup' => render(node_page_edit($node)),
'#weight' => 10,
);
}
also for new (empty) form you should use node_add function function node_add($type