Add custom column in-between people/users admin page table drupal 7 - drupal-7

I have created a custom column to display last user changed time, but I need this field to be insert before OPERATIONS column. Below is my code which append my custom field at the end.
function meme_user_update_form_user_admin_account_alter(&$form, &$form_state, $form_id) {
$changed_column = array('changed' => array(
'data' => 'LAST CHANGED',
'field' => 'u.changed'
));
$form['accounts']['#header'] = $form['accounts']['#header'] + $changed_column;
foreach ($form['accounts']['#options'] as $key => $row) {
$user_object = user_load($key);
$user_language = ($user_object->language) ? $user_object->language : LANGUAGE_NONE;
$form['accounts']['#options'][$key]['changed'] = $user_object->field_user_changed[$user_language][0]['value'];
}
}

Found an answer, I think this might help someone.
function meme_user_update_form_user_admin_account_alter(&$form, &$form_state, $form_id) {
$changed_column = array(
'data' => 'LAST CHANGED',
'field' => 'u.changed'
);
$operation_column = array_pop($form['accounts']['#header']);
$form['accounts']['#header']['changed'] = $changed_column;
$form['accounts']['#header']['operations'] = $operation_column;
foreach ($form['accounts']['#options'] as $key => $row) {
$user_object = user_load($key);
$user_language = ($user_object->language) ? $user_object->language : LANGUAGE_NONE;
$operation_column = array_pop($form['accounts']['#options'][$key]);
$form['accounts']['#options'][$key]['changed'] = $user_object->field_user_changed[$user_language][0]['value'];
$form['accounts']['#options'][$key]['operations']['data'] = $operation_column;
}
}

Related

Drupal 7 create and send mailchimp campaign programmatically

How to create and send mailchimp campaign programmatically in drupal 7 ?
function kf_mailchimp_create_campaign() {
if (!isset($_GET['cron_key']) || ($_GET['cron_key'] != 'kQ7kOy4uRgPJd1FX1QQAERPeSYuPjp1qBW65goYcbDQ')) {
watchdog('kf_mailchimp', 'Invalid cron key !cron_key has been used to create campaign.', array('!cron_key' => $_GET['cron_key']));
drupal_exit();
}
$data['site_url'] = url('<front>', array('absolute' => TRUE));
$data['site_logo'] = theme_image(array(
'path' => drupal_get_path('theme', 'knackforge') . '/logo.png',
'alt' => 'KnackForge',
'attributes' => array('border' => 0),
));
$options = array(
'list_id' => $mc_list_id, // Change this to match list id from mailchimp.com.
'from_email' => variable_get('site_mail'),
'from_name' => 'KnackForge',
'to_email' => variable_get('site_name')
);
$type = 'regular';
$q = mailchimp_get_api_object(); // Make sure a list has been created in your drupal site.
$results = views_get_view_result('deal_mailchimp', 'page');
// Check to prevent sending empty newsletter
if (empty($results)) {
watchdog('kf_mailchimp', 'No active deals to send for today');
drupal_exit();
}
$data['deals'] = views_embed_view('deal_mailchimp', 'page');
$content = array(
'html' => theme('kf_mailchimp', $data),
);
$options['subject'] = t('Newsletter');
$options['title'] = $options['subject'] . ' - ' . date('r');
$options['tracking'] = array(
'opens' => TRUE,
'html_clicks' => TRUE,
'text_clicks' => TRUE
);
$options['authenticate'] = false;
$options['analytics'] = array('google'=>'atphga');
$cid = $q->campaignCreate($type, $options, $content);
watchdog('kf_mailchimp', 'Created campaign');
$result = $q->campaignSendNow($cid);
watchdog('kf_mailchimp', 'campaignSendNow() response !result', array('!result' => '<pre>' . print_r($result, 1) . '</pre>'));

How to send data to custom block content

I'm trying to create a module that will display some last entries from database. I'd like to send last entry object to template file (guestbook-last-entries.tpl.php), that looks like that
<p><?php render($title); ?></p>
<?php echo $message; ?>
I have a function that implements hook_theme
function guestbook_theme() {
return array(
'guestbook_last_entries' => array(
'variables' => array(
'entries' => NULL,
),
'template' => 'guestbook-last-entries'
),
);
}
one that do preprocess
function template_preprocess_guestbook_last_entries(&$variables) {
$variables = array_merge((array) $variables['entries'], $variables);
}
and functions that implements hook_block_view
function guestbook_block_view($delta = '') {
switch ($delta) {
case 'guestbook_last_entries':
$block['subject'] = t('Last entries');
$block['content'] = array();
$entries = guestbook_get_last_entries(variable_get('guestbook_m', 3));
foreach ($entries as $entry) {
$block['content'] += array(
'#theme' => 'guestbook_last_entries',
'#entries' => $entry,
);
}
break;
}
return $block;
}
function that gets data from database
function guestbook_get_last_entries($limit = 3) {
$result = db_select('guestbook', 'g')
->fields('g')
->orderBy('posted', 'DESC')
->range(0, $limit)
->execute();
return $result->fetchAllAssoc('gid');
}
But in this case I get only one entry displayed. Can anyone tell me how to resolve this, how should I build that $block['content']?
Thank you
This here wont work:
$block['content'] += array(
'#theme' => 'guestbook_last_entries',
'#entries' => $entry,
);
Maybe you want this if you need an array as the result:
// note that I replaced += with a simple = and added two brackets that will create a new element in that array $block['content']
$block['content'][] = array(
'#theme' => 'guestbook_last_entries',
'#entries' => $entry,
);

CakePHP Pagination: how can I sort by multiple columns to achieve "sticky" functionality?

I see that this paginate can't sort two columns at the same time ticket is still open, which leads me to believe that what I'm trying to do is not possible without a workaround. So I guess what I'm looking for is a workaround.
I'm trying to do what many message boards do: have a "sticky" function. I'd like to make it so that no matter which table header link the user clicks on to sort, my model's "sticky" field is always the first thing sorted, followed by whatever column the user clicked on. I know that you can set $this->paginate['Model']['order'] to whatever you want, so you could hack it to put the "sticky" field first and the user's chosen column second. The problem with this method is that pagination doesn't behave properly after you do it. The table header links don't work right and switching pages doesn't work right either. Is there some other workaround?
User ten1 on the CakePHP IRC channel helped me find the solution. I told him that if he posted the answer here then I would mark it as the correct one, but he said I should do it myself since he doesn't have a Stack Overflow account yet.
The trick is to inject the "sticky" field into the query's "order" setting using the model's "beforeFind" callback method, like this:
public function beforeFind($queryData) {
$sticky = array('Model.sticky' => 'DESC');
if (is_array($queryData['order'][0])) {
$queryData['order'][0] = $sticky + $queryData['order'][0];
}
else {
$queryData['order'][0] = $sticky;
}
return $queryData;
}
What you can do is code it in the action. Just create the query you want when some parameters exist on the URL. (parameters has to be sent by GET)
For example:
public function posts(){
$optional= array();
if(!empty($this->params->query['status'])){
if(strlower($this->params->query['status']=='des')){
$optional= array('Post.status DESC');
}
else if(strlower($this->params->query['status']=='asc')){
$optional= array('Post.status ASC');
}
}
if(!empty($this->params->query['department'])){
//same...
}
//order first by the sticky field and then by the optional parameters.
$order = array('Post.stickyField DESC') + $optional;
$this->paginate = array(
'conditions' => $conditions,
'order' => $order,
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));
}
I have used something similar to filter some data using $conditions instead of $order and it works well.
You can use custom field for sorting and update pagination component.
Controller code
$order['Document.DATE'] = 'asc';
$this->paginate = array(
"conditions"=> $conditions ,
"order" => $order ,
"limit" => 10,
**"sortcustom" => array('field' =>'Document.DATE' , 'direction' =>'desc'),**
);
Changes in pagination component.
public function validateSort($object, $options, $whitelist = array()) {
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
}
if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
$field = key($options['order']);
if (!in_array($field, $whitelist)) {
$options['order'] = null;
}
}
if (!empty($options['order']) && is_array($options['order'])) {
$order = array();
foreach ($options['order'] as $key => $value) {
$field = $key;
$alias = $object->alias;
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
if ($object->hasField($field)) {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
}
}
**if(count($options['sortcustom']) > 0 )
{
$order[$options['sortcustom']['field']] = $options['sortcustom']['direction'];
}**
$options['order'] = $order;
}
return $options;
}
Easy insert 'paramType' => 'querystring',
Show Code Example:
$this->paginate = array(
'conditions' => $conditions,
'order' => array(
'Post.name' => 'ASC',
'Post.created' => 'DESC',
),
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));

Why this code add only a single data from an array into a menu table

I am able to obtain the $data array from a form and I can generate data for each item... But during the binding and storing with jTable object it saves only the latest item why... I am using native JTableMenu class to bind and save by using my own class which is extended by native one. Early trials I used database object to save items with sql syntax but some columns of table remains empty lft and rgt to fill them I used table object but it gives this issue.
The whole code is following:
function addcumulative($data){
$db = JFactory::getDBO();
$component = & JComponentHelper::getComponent('com_dratransport');
$menus = array();
$query = array();
$countries = DraTransportHelperArrays::countries();
$cities = DraTransportHelperArrays::cities();
$title = array();
$alias = array();
$path = array();
$link = array();
if(empty($data['parent_id']) && $data['parent_id'] == 0){
$data['parent_id'] = 1;
}else{
$parent_id = explode('.',$data['parent_id']);
$data['parent_id'] = $parent_id[1];
}
if(!empty($data['locationQuery'])){ //actually this part will be used
$loc = ($data['locationQuery'] == 'countries') ? $countries : $cities['Turkey'] ;
foreach($loc as $k => $c){
$query[0] = $data['general'];
foreach($data as $key => $dat){
if(!empty($dat) && strpos($key,'Query') !== false){
$v = explode('Q',$key);
if($v[0] !== 'location'){
$query[] = '&'.$v[0].'='.$dat;
}else{
$query[] = '&'.$dat.'='.$k;
}
}
}
$title[] = $data['viewQuery'].'-'.$k;
$alias[] = $data['viewQuery'].'-'.$k;
$path[] = $data['viewQuery'].'-'.$k;
$link[] = implode('',$query);
$query = array();
}
}else{
$query[0] = $data['general'];
foreach($data as $key => $dat){
if(!empty($dat) && strpos($key,'Query') !== false){
$v = explode('Q',$key);
$query[] = '&'.$v[0].'='.$dat;
}
}
$link[] = implode('',$query);
}
foreach($link as $n => $l){
$menus[] = array(
'menutype' => $data['menutype'],
'title' => $title[$n],
'alias' => $alias[$n],
'path' => $path[$n],
'link' => $link[$n],
'type' => 'component',
'published' => 1,
'parent_id' => $data['parent_id'],
'level' => 1,
'component_id' => $component->id,
'access' => $data['access'],
'params' => $data['params'],
'language' => '*'
);
}
$count = $data['count'] == 0 ? count($loc) : $data['count'];
foreach($menus as $menu){
// Bind the data.
$table = $this->getTable();
$table->bind($menu);
$table->store();
}
}
Yes you are totally right. Let say $countries=array('England','France','Germany'); then I wrote my code in model to generate links in #__menu table. So I write
foreach($countries as $country){
$link='index.php&option=com_mycomponent&view=members&type=1&countries='.$country;
$table->bind();
$table->save();
}
I am generating links like this, view and the type values in query comes from the form submitted to make parmaters same for all menus except countries;
and I assign all parametes to manu item and menu items to an array as array item...
to save database the table comes with nested.
$menus->$each menu as $menus array item->menu item parameters
while the table is first created in above code code just adds the last menu item but if I take it insede the foreach it adds all of them but parent_id and level parameters assigned to 0 bye the native code altought I set them as 1

Populating #options, #header for tableselect in ajax callback function

What I am trying to do is display a table with checkboxes on the press of a button by ajax. The table should be initially hidden and get populated on the fly by a function call.
If initially I load $options1 with some dummy values , then after ajax call it throws in an error saying-
Notice: Undefined index: red in theme_tableselect() (line 3285 of
D:\wamp\www\drupal7\includes\form.inc).
where 'red' is the index of a dummy row value and #options don't get populated with the new values. What is the way to get this working ?
Here is the code for the form-
$form['mltag_new']['tag'] = array(
'#type' => 'button',
'#value' => t("Suggest Tags"),
'#ajax' => array(
'callback' => 'mltag_suggest_tags_ajax',
'wrapper' => 'mltag_suggest_tags_table_div',
'effect' => 'slide',
),
);
$options1 = array(); //initial dummy values
$options1['red']['tag'] = "A red row";
$options1['red']['chi'] = "A red row";
$form['mltag_new']['myselector'] = array (
'#type' => 'tableselect',
'#title' => 'My Selector',
'#header' => $header,
'#options' => $options1,
'#prefix' => '<div id="mltag_suggest_tags_table_div">',
'#suffix' => '</div>',
);
return $form;
and the Ajax callback looks something like this-
function mltag_suggest_tags_ajax($form, $form_state) {
//$content has some content
//pass the content to a function
include_once 'includes/content_tag.inc';
$tags = mltag_content_tag($content, variable_get('algo_type'), 20);
if (empty($tags)) {
$output .= t('Content is insufficient to generate Tags using this algorithm. <br>Please choose other algorithm from Settings Page.');
$form['mltag_new']['sample_text']['#markup'] = $output;
return $form['mltag_new']['sample_text'];
}
else {
$algo = variable_get('algo_type');
if ($algo == 1) {
$header = array(
'tag' => t('Tag'),
'frequency' => t('Frequency'),
);
$options = array();
foreach ($tags as $key => $value) {
$options[$key] = array(
'tag' => $key,
'frequency' => $value,
);
}
}
elseif ($algo == 2) {
$header = array(
'tag' => t('Tag'),
'chi' => t('Chi Square Value'),
);
$options = array();
foreach ($tags as $key => $value) {
$options[$key] = array(
'tag' => $key,
'chi' => $value,
);
}
}
$form['mltag_new']['myselector']['#header'] = $header;
$form['mltag_new']['myselector']['#options'] = $options;
return $form['mltag_new']['myselector'];
}
}
I replied to your post on Drupal.org about how I'm working on a somewhat similar problem. Try adding
$form['mltag_new']['myselector'] =
form_process_tableselect($form['mltag_new']['myselector']);
just before your return. Hopefully that helps you more than it did me. Beware that the #options just get rendered when the block reloads from the ajax, but the original $form object doesn't seem to be aware.
I know that this is a few years later, but I found this while searching for my own solution:
The tableselect module creates checkboxes in the $ form that have to be removed. in the example above, they would be in $form['mltag_new']['myselector'] with keys equal to the original $option1 in your original code. If you unset those, then call
$form['mltag_new']['myselector'] = form_process_tableselect($form['mltag_new']['myselector']);
before your return, it will eliminate the dummy rows.

Resources