TYPO3: Generate in realURL multiple URLs with the same postVarSets in different levels - typo3

In my TYPO3 there are multiple storages with different sport activities.
The one belongs to place A, the other to place B with different content.
Now I would like to generate the followingURLs.
The first one is for general, the other one are specific.
/sport/golf
/place-a/sport/golf
/place-b/sport/golf
sport is decoded to /sport-detail/controller/action/sport/
I used the default lookUpTable, but the URLs cant be resolved.
'lookUpTable' => array(
'table' => 'tx_myext_domain_model_sport',
'id_field' => 'uid',
'alias_field' => "url",
'addWhereClause' => ' AND deleted = 0 AND hidden = 0',
'useUniqueCache' => 1,
'languageGetVar' => 'L',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-',
),
)
What is needed to create valid URLs, without golf-1 etc.. for all levels?

I'm not exactly sure what you want to do. Are "place-a" and "place-b" separate pages or are these additional parameters for your ext?Also, could you provide the full RealURL config?
Depending on the targeted performance you could also just avoid using the UniqueCache...

Finally I wrote a UserFunction that fulfills my needs. In this function I extend the given lookuptable function from realURL and fetch me the values yourself.
The model has been renamed in the meantime to activity.
I do now save the detail pid for the show action and the storage pid in the sport model so I can search the whole URL path to find place name and lookup the storage pid. With the storage pid of the place I can find the right activity. And with a correct lookup in the database I can return a valid ID.
For SEO reasons I added a new field URL to the model that contains the string in the URL path. In the id2alias method I return the url value of the activity with the given ID.
I noticed one behavior that realURL doesn't find the correct entry in the caching table once all the parameters are hashed, so I had to exclude the activity GETvar from cHash generation.
$GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'] = tx_myext_activity[activity]
After all this is my working setup :-)
RealURL config:
'GETvar' => 'tx_myext_activity[activity]',
'type' => 'user',
'languageGetVar' => 'L',
'languageField' => 'sys_language_uid',
'useUniqueCache' => 0,
'userFunc' => 'EXT:MyUserFunc.php:&MyUserFunc->main'
The UserFunction handles now the URL generation.
<?php
class MyUserFunc
{
protected $sys_language_uid;
protected $params;
protected $localizedStrings;
public function main($params, $ref)
{
if ($params) {
$this->params = $params;
$dirParts = $this->params['pObj']->dirParts;
//language
$this->sys_language_uid = 0;
//is realUrl in encode or decode
if ($this->params['decodeAlias']) {
return $this->alias2id($this->params['value']);
} else {
return $this->id2alias($this->params['value']);
}
}
}
/*
* Generate URL param
*/
protected function id2alias($value)
{
$sysLanguageToBuild = $this->params['pathParts'][0];
//if not default, use l10n_parent with sysuid
if ($sysLanguageToBuild > 0) {
$additionalWhere = ' AND l10n_parent = ' . (int)$value;
$additionalWhere .= ' AND sys_language_uid = ' . (int)$sysLanguageToBuild;
} else {
$additionalWhere = ' AND uid = ' . (int)$value;
}
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'url',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
$activityRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
if (is_array($activityRow)) {
return $activityRow['url'];
}
return 'undefined';
}
/**
* Decode string to uid
* respect activities with different pid
*
* #param $value
* #return int
*/
protected function alias2id($value)
{
$dirParts = $this->params['pObj']->dirParts; //get array of complete path
$place = htmlspecialchars($this->params['pObj']->dirParts[2]); //get place
//transform place string
$place = strtolower($place);
$place = preg_replace("/[^A-Za-z0-9\s-._\/]/", "", $place);
$place = trim(preg_replace("/[\s-]+/", " ", $place));
//Query Place
$placeRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, activity_storage_page',
'tx_myext_domain_model_place',
'deleted = 0 AND hidden = 0 AND sys_language_uid = '. $this->sys_language_uid .
' AND LOWER(name) = "' . $place . '"'
);
$placeRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($placeRes);
//Query Activity
if (is_array($placeRow)) {
$additionalWhere .= " AND tx_myext_domain_model_activity.pid = '" . (int)$placeRow['activity_storage_page'] . "'";
}
$additionalWhere = " AND tx_myext_domain_model_activity.sys_language_uid = " . $this->sys_language_uid;
$additionalWhere .= " AND tx_myext_domain_model_activity.url = '" . $value . "'";
$additionalWhere .= " AND tx_myext_domain_model_activity.pid = '" . $pid . "'";
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'tx_myext_domain_model_activity.uid',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
return (int)$row['uid'];
}
//catch old URLs and return uid
$additionalWhere = " AND tx_myext_domain_model_activity.sys_language_uid = " . $this->sys_language_uid;
$additionalWhere .= " AND tx_myext_domain_model_activity.name = '" . $value . "'";
$resElse = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'tx_myext_domain_model_activity.uid',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resElse)) {
return (int)$row['uid'];
}
return false;
}
}

Related

How to load post ID using the gform_form_post_get_meta filter?

Trying to load post ID (and then some ACF field) of the post, where the form is currently embedded. Using get_the_id() or global $post w/ $post->ID returns NULL.
Loading post ID works correctly when using the other Gravity Forms filters (e.g. gform_admin_pre_render), but I was told using the gform_form_post_get_meta is the better way to do ths. What is the right approach for this?
add_filter( 'gform_form_post_get_meta' , 'my_populate_cpt_as_choices' );
function my_populate_cpt_as_choices( $form ) {
$current_post_id = get_the_id();
$postargs = array(
'post_type' => 'suhlasy',
'post_status' => 'publish',
'posts_per_page' => '-1',
);
$posts = get_posts( $postargs );
$input_id = 1; // this makes sure the checkbox labels and inputs correspond
foreach ( $posts as $post ) {
//skipping index that are multiples of 10 (multiples of 10 create problems as the input IDs)
if ( $input_id % 10 == 0 ) {
$input_id++;
}
$post_id = $post->ID;
$id_souhlasu = 1200 + $input_id;
$title = get_the_title($post_id);
$checkbox_text = get_field('checkbox_text', $post_id);
$text_suhlasu = get_field('text_suhlasu', $post_id);
$kategoria = get_field('kategoria_suhlas', $post_id);
// getting other fields for this post to display as values or checkbox labels
$nazev_souhlasu = GF_Fields::create( array(
'type' => 'consent',
'id' => $id_souhlasu, // The Field ID must be unique on the form
'formId' => $form['id'],
'isRequired' => true,
'label' => $title,
'parameterName' => 'my_custom_parameter',
'checkboxLabel' => $checkbox_text,
'description' => '<h2>' . $current_post_id . $post_id . $kategoria . '</h2><br>' . $text_suhlasu,
'pageNumber' => 1, // Ensure this is correct
) );
$form['fields'][] = $nazev_souhlasu;
$input_id++;
}
return $form;
}

Paragraph breaks missing from shortcode output

I created a shortcode in Wordpress to perform a query and display the content, but the content line breaks are being removed.
add_shortcode( 'resource' , 'Resource' );
function Resource($atts) {
$atts = shortcode_atts( array(
'category' => ''
), $atts );
$categories = explode(',' , $atts['category']);
$args = array(
'post_type' => 'resource',
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page'=> -1,
'tax_query' => array( array(
'taxonomy' => 'category',
'field' => 'term_id',
'operator' => 'AND',
'terms' => $categories
) )
);
$string = '';
$query = new WP_Query( $args );
if( ! $query->have_posts() ) {
$string .= '<p>no listings at this time...</p>';
}
while( $query->have_posts() ){
$query->the_post();
$string .= '<div id="links"><div id="linksImage">' . get_the_post_thumbnail() . '</div>
<div id="linksDetails"><h1>'. get_the_title() .'</h1><p>' . get_the_content() . '</p>
<p>for more information CLICK HERE</div></div>';
}
wp_reset_postdata();
$output = '<div id="linksWrapper">' . $string . '</div>';
return $output;
}
Any suggestion on why this is happening and what to do to fix it. This is only happening on the shortcode output. On regular pages - the content displays correctly.
found a solution through more searches:
function get_the_content_with_formatting ($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
$content = get_the_content($more_link_text, $stripteaser, $more_file);
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
return $content;
}
works perfect, so I thought I would share..

PHP- PDO get metadata from database

I want to get the metadata from a database with a table 'friends'
id name
1 Herbert
2 LG
3 Levins
Here is the code I was trying to get the data.
<?php
$dsn = 'mysql:host=localhost;dbname=postgre';
$username = 'root';
$password = '';
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$db = new PDO($dsn, $username, $password, $options);
$stmt = $db->query("SELECT * FROM friends");
$cnt_columns = $stmt->columnCount();
for($i = 0; $i < $cnt_columns; $i++) {
$metadata = $stmt->getColumnMeta($i);
var_dump($metadata);
}
?>
When I execute the code:, it displays
array
'native_type' => string 'LONG' (length=4)
'pdo_type' => int 2
'flags' =>
array
empty
'table' => string 'friends' (length=7)
'name' => string 'id' (length=2)
'len' => int 11
'precision' => int 0
array
'native_type' => string 'VAR_STRING' (length=10)
'pdo_type' => int 2
'flags' =>
array
empty
'table' => string 'friends' (length=7)
'name' => string 'name' (length=4)
'len' => int 60
'precision' => int 0
Till here, it is giving the correct count of rows, but I need the result to display as it looks in the my database like
Output:
id name
1 Hebert
2 LG
3 Levins
How could I get all my fields as it is like a table in my database using metadata.
Use columnCount.
$stmt = $db->query("SELECT * FROM friends");
$cnt_columns = $stmt->columnCount();
for($i = 0; $i < $cnt_columns; $i++) {
$metadata = $stmt->getColumnMeta($i);
var_dump($metadata);
}
By the way, getColumnMeta is experimental. Not recommended to use. Why do you want to use it?
For the desired output, you don't need metadata. Just loop through the results:
$sql = "SELECT * FROM friends";
$stmt = $db->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
// field names
if(count($result) > 0) {
foreach($result[0] as $k => $v) {
if(!is_int($k)) {
echo $k . "\t";
}
}
}
echo PHP_EOL;
// data
foreach ($result as $row) {
foreach($row as $k => $v) {
if(!is_int($k)) {
echo $row[$k] . "\t";
}
}
echo PHP_EOL;
}

How to retrieve all comments of the Fan Page

I need to get all comments of the Fan Page. Not only from the wall, but from the albums, photos, notes, etc.
I solved this problem in such a way. First I get all objects (albums, notes, etc.) of the Fan Page. Second I get commets to each object, using FQL multi query.
// Import comment list
$facebook = \Yii::app()->facebook->setUserAccessToken();
$commentsColumns = array(
'xid', 'object_id', 'post_id', 'fromid', 'time', 'text', 'username',
'reply_xid', 'post_fbid', 'app_id', 'likes', 'comments', 'user_likes',
'is_private', 'id',
);
$offset = 0;
$limit = 30;
while (($offset <= count($objectIdList)) && ($offset <= count($postIdList))) {
$currentObjectIdList = array_slice($objectIdList, $offset, $limit);
$currentPostIdList = array_slice($postIdList, $offset, $limit);
$multiQuery = array(
'comments' =>
' SELECT '.implode(', ', $commentsColumns).' '.
' FROM comment '.
' WHERE ((object_id IN ('.implode(',', $currentObjectIdList).')) '.
' OR (post_id IN ('.implode(',', $currentPostIdList).'))) '.
' AND (time >= ' . $lastCommentTime . ') ' .
' ORDER BY time DESC '.
' LIMIT 1000 ',
'users' =>
' SELECT uid, name ' .
' FROM user ' .
' WHERE uid IN (SELECT fromid FROM #comments) ',
'pages' =>
' SELECT page_id, name ' .
' FROM page ' .
' WHERE page_id IN (SELECT fromid FROM #comments) '
);
$multiQueryResult = $facebook->api(array(
'method' => 'fql.multiquery',
'queries' => $multiQuery
));
// Parse multi query results
$from = array();
foreach ($multiQueryResult as $result) {
switch ($result['name']) {
case 'comments':
$commentList = $result['fql_result_set'];
break;
case 'users':
case 'pages':
foreach ($result['fql_result_set'] as $set) {
switch ($result['name']) {
case 'users':
$from[$set['uid']] = $set['name'];
break;
case 'pages':
$from[$set['page_id']] = $set['name'];
break;
}
}
break;
}
}
// Save comments to local DB
foreach ($commentList as $commentData) {
$comment = new Comment();
$comment->fbId = $commentData['id'];
$comment->fbPageId = $this->fbId;
$comment->from = array(
'id' => $commentData['fromid'],
'name' => isset($from[$commentData['fromid']]) ? $from[$commentData['fromid']] : null,
);
$comment->message = $commentData['text'];
$comment->created_time = $commentData['time'];
$comment->likes = $commentData['likes'];
$comment->save();
}
// Next step
$offset = $offset + $limit;
}
This solution works, but is not pretty fast. Has anyone know better solution?
I think you can use the graph API method given below,
https://graph.facebook.com/userid/feed to get all the feeds of the user .It will return an json array,from there you can collect the comments,statuses etc etc

Multistep drupal form with tables

Can anyone tell me how to make a multi-step drupal form which prints a table in one of the steps?-
This is the code I already have, it corresponds to the second step of the form. It throws me this error:
Fatal error: Cannot unset string offsets in C:\wamp\www\academicus\includes\form.inc on line 497
function listarAlumnos($nombre, $apellido) {
if($nombre=='') {
$consulta="SELECT * FROM Pinteres WHERE PinApe1='".$apellido."' or PinApe2='".$apellido;
} else if ($apellido=='') {
$consulta="SELECT * FROM Pinteres WHERE PinNom1='".$nombre."' or PinNom2='".$nombre."'";
} else {
$consulta="SELECT * FROM Pinteres WHERE (PinNom1='".$nombre."' or PinNom2='".$nombre."') AND (PinApe1='".$apellido."' or PinApe2='".$apellido."')";
}
$resultado=consultarContacta($consulta);
$form=array();
$header = array(t('Id'), t('Primer nombre'), t('Segundo nombre'), t('Primer apellido'), t('Segundo apellido'), t('Direccion'), t('Telefono'), t('Celular'), t('Email'));
$rows = array();
while ($rs=odbc_fetch_array($resultado)) {
$row=array();
$id=$rs['PinId'];
$primerNombre=$rs['PinNom1'];
$segundoNombre=$rs['PinNom2'];
$primerApellido=$rs['PinApe1'];
$segundoApellido=$rs['PinApe2'];
$direccion=$rs['PinDir'];
$telefono=$rs['PinTelPri'];
$celular=$rs['PinTelCel'];
$email=$rs['PinEMail'];
$row[] = $id;
$row[] = $primerNombre;
$row[] = $segundoNombre;
$row[] = $primerApellido;
$row[] = $segundoApellido;
$row[] = $direccion;
$row[] = $telefono;
$row[] = $celular;
$row[] = $email;
$rows[] = $row;
};
$form['IdIngresado'] = array (
'#title' => t('Id interesado a importar'),
'#type' => 'textfield',
'#required' => TRUE,
'#description' => t('Ingrese el id del interesado a importar de los listados arriba.')
);
$form['CedulaIngresada'] = array (
'#title' => t('Cedula interesado a importar'),
'#type' => 'textfield',
'#required' => TRUE,
'#description' => t('Ingrese la cedula del interesado a importar.')
);
$form['finalizar'] = array (
'#type' => 'submit',
'#value' => t('Finalizar')
);
$output .= theme('table', $header, $rows);
$output .= drupal_render($form);
return $output;
}
I could make it work using some code like this:
$form['serial'] = array(
'#type' => 'textfield',
'#title' => t('serial number'),
'#prefix' => '<table><tr><td>',
'#suffix' => '</td>',
);
but I know it's not the proper way of doing it.
I assume you know how to do the multi-step form. For the table, you can use Drupal's table theme function. If the table contains only markup, you can do something like this:
$form['table'] = array ('#value' => theme('table', $headers, $rows));
$headers are the table headers and $rows are your data.
If the table contains actual form elements (such as selects, textfields, etc.), you can wrap them in a form element that calls a theme function, like so:
$form['table'] = array ('#theme' => 'output_table');
$form['table']['element_1'] = array (...);
$form['table']['element_2'] = array (...);
Within 'theme_output_table', generate your $headers and $rows to feed to 'theme_table' by calling 'drupal_render' on the relevant form elements that are children of $form['table'].