I'm trying to build a placeholder meta description for a page, in case the user hasn't included a description in the CMS.
I have started with the following code, but of course it fails if any of the other variables are empty too, such as $phone, $location['zip'] and so on.
<?php
if (!empty($description)) {
echo '<meta name="description" content="' .$description . '">';
}
else {
// Should return: Apple is a business located in Palo Alto, 95014. Call 408.996.1010...
$description = $name . ' is a ' . strtolower($category) . ' located in ' . $location['city'] . ', ';
$description .= $location['zip'] . '. Call ' . $phone . ' for more details today.';
echo '<meta name="description" content="' . $description . '">';
} ?>
What's the most efficient way to build a description in this way? Currently I can only think of nested if statements which sounds messy and I'm sure there must be a clean way to do this.
add a function to check if value is set?
i.e.
function checkData($data) {
if(!empty($data)) {
return $data;
} else {
return '';
}
}
$description = checkData($name) . ' is a ' . strtolower(checkData($category)) . ' located in ' . checkData($location['city']) . ', ';
As the description is something that varies based on the input, put it into a function or class of it's own to encapsulate it:
/**
* build a description based on various input variables
* #return string
*/
function build_description($description, $name, $category, array location, $phone) {
// build the description as you see fit.
}
$description = build_description(compact('description', 'name', 'category'));
$metaDescription = sprintf('<meta name="description" content="%s"', htmlspecialchars($description));
that done, the concrete implementation within build_description can contain a lot of complex statements, while the rest of the program can deal with it as if it is something simple.
However, this does not answer how you could code it inside that function. But as the data of the output of that function heavily depends on the input of that function, you can only deal with all aspects the arguments do impose.
The other variables defined shouldn't be string but part of an object such as... Description.
In this case, it would be easier, calling a Description->isEmpty() that returns true if one of those variables are empty.
If you are stuck with this configuration, you still can make an array:
$myArray=array($name, $category,...);
and check in a loop or maybe the return of in_array('',$myArray)
Related
I'm quite new to PHP, so this is probably a stupid question.
I have an if/else that I need to use in a return tag, but it doesn't work. How should I structure this?
This is the tag:
return '… <div class="read"><a class="read-more hvr-icon-forward" href="'. get_permalink($post->ID) . '">' . "CODE HERE" . '</a></div>';
This is what I need to output in "CODE HERE"
$status = of_get_option('read_more');
if (empty($status)) {
echo 'Sorry, the page does not exist.';
} else {
_e($status);
}
https://jsfiddle.net/33nv1xpa/1/
Do I get it right, you have a structure like
return *SOME_STRING* SOME CODE WITH ";" *SOME_STRING*
?
I would highly recommend, to create a string var containing the text you want to return and finally only return that string.
$echoCode = result from CODE HERE
$returnText = "<div>blalba</div>" . $echoCode . "<div>blabla</div>";
return $returnText;
You can do it by using the ternary operator, and putting the variable assignment in parenthenses.
return "...". (($status = get_option('status')) ? $status : _e()) ."...";
Otherways, I suggest to put this functionality in a function, or at least in a plain variable.
Coding like this makes the whole thing unreadable.
Also, you're trying to run a wordpess function in an online parser which will undeniably miss these features!
Well you can use the Php eval function (http://php.net/manual/en/function.eval.php). It evaluates a string as Php code. So you can assign the result of eval to a variable called $code_here:
$code_here = "$status = of_get_option('read_more');
if (empty($status)) {
echo 'Sorry, the page does not exist.';
} else {
_e($status);
}";
$code_here = eval($code_here);
First lemme tell you what i am trying to achieve here . Suppose there is a url like this http://www.example.com/?id=12345 now what i want is if there is an id parameter available in the url i want to append the same parameter to every url on that page . Opencart has a url library that generates url i am sure you all must be familiar with it too , i found a way to do what i want but it's working at just some random parts of the website like categories url's are generating with id parameter appended to it and other's dont .
here's what i tried so far
File : System/libray/url.php
here's the function
public function link($route, $args = '', $connection = 'NONSSL') {
if ($connection == 'NONSSL') {
$url = $this->url;
}else {
$url = $this->ssl;
}
$url .= 'index.php?route=' . $route;
if ($args) {
$url .= str_replace('&', '&', '&' . ltrim($args, '&'));
}
foreach ($this->rewrite as $rewrite) {
$url = $rewrite->rewrite($url);
}
if(isset($_GET['id']))
{
if(!empty($this->request->get['id']))
$url .= '&id='.$this->request->get['id'];
if(!empty($_GET['id']))
{
$url .= '&id='.$_GET['id'];
}
}
return $url;
}
The problem is that not everything uses this method to generate its URLs.
For example, anything to do with banners (e.g. the Carousel module) uses links that the admin sets manually in System->Design->Banners, so you would also need to edit the code for this too. The simplest and probably the correct way is to edit the data that the models spit out e.g.
model_design_banner->getBanner() becomes
public function getBanner($banner_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "banner_image bi LEFT JOIN " . DB_PREFIX . "banner_image_description bid ON (bi.banner_image_id = bid.banner_image_id) WHERE bi.banner_id = '" . (int)$banner_id . "' AND bid.language_id = '" . (int)$this->config->get('config_language_id') . "'");
if (isset($_GET['id'])) {
array_walk($query->rows, function(&$value) {
$value['link'] .= '&id=' . $_GET['id'];
});
}
return $query->rows;
}
It's either that, or edit the output in every single controller that uses this method.
That's just an example for banners, though. I don't recall off-hand which other modules will need to be edited, but if there's a particular one that's making you scratch your head, let me know and I'll give you another example to fix it.
Not quite sure how to word the title better.
What i need to do, is call a method with call_user_func. The method i'm calling accept several different variables (var1, var2, var3 etc), not an array. The problem is, when calling the function i need to pass the array i have as seperate variables to the method. Let me show you.
Here's my method:
class Test {
public function testing_cronjob($p1, $p2, $p3, $p4, $p5) {
echo 'p1 = ' . $p1 . '<br />';
echo 'p1 = ' . $p2 . '<br />';
echo 'p1 = ' . $p3 . '<br />';
echo 'p1 = ' . $p4 . '<br />';
echo 'p1 = ' . $p5 . '<br />';
}
}
And here's how i currently (try) to call it:
$obj = new Test();
call_user_func(array($obj, 'testing_cronjob'), $params);
The method runs, but it only gets one variable, which is not what i want.
$params look like this:
$params = array(
0 => 'first one',
1 => 'second one',
2 => 'third param!',
3 => 'oh and im fourth!!',
4 => 'im last, fml! :('
)
The way i got myself into this situation, is because i'm creating a cronjob model. It accepts params along with class and method name. It's all stored in a database, and when it runs, i need to be able to send the $params to the method as intended.
I can't rewrite how methods accept variables, because that would be way too much work. I'm going to be calling several (10+) methods from the cronjob, all of which are pretty well used in the application. I'm also not sure how i would re-write it, but if you have any suggestions about that, let me know.
Also, i'm using codeigniter if that matters. If i forgot to mention anything or you want more code, just drop a comment.
Is this possible? Are there any workarounds? Any suggestions are welcome!
You have to use call_user_func_array instead:
$obj = new Test();
call_user_func_array(array($obj, 'testing_cronjob'), $params);
Is it possible to write a NetBeans code template for using all the arguments declared in a function's header (e.g. for calling another function with these variables)? The number of the arguments can be different, so it doesn't seem to be easy.
For example, sometimes I want to print out all the arguments in a function for debugging purposes.
Here's an example usage (calling dsm() function multiple times depending on the number of the arguments):
function testModule_theme($existing, $type, $theme, $path) {
dsm($existing, '$existing in ' . __FUNCTION__ . '()');
dsm($type, '$type in ' . __FUNCTION__ . '()');
dsm($theme, '$theme in ' . __FUNCTION__ . '()');
dsm($path, '$path in ' . __FUNCTION__ . '()');
return array(
// ......
);
}
Here's another one:
function testModule_block_view($delta = '') {
dsm($delta, '$delta in ' . __FUNCTION__ . '()');
$block = array();
// .....
return $block;
}
As you can see, there are 4 arguments in the first case, and only 1 in the second. The name of the arguments is also changing depending on the given function.
There's a code template I already wrote for using dsm() function:
dsm($$${VARIABLE newVarName default="variables"}, '$$${VARIABLE} in '.__FUNCTION__.'()');
this way I just type ddsm, hit Tab, and then I have to type the exact name of the variable. So it would print out the following:
dsm($variables, '$variables in ' . __FUNCTION__ . '()');
After that, I can change the variables part, and type another name, and the same would be used in the string. An example:
But I'm still too laggard to type that stuff :D, and I'm curious if there is a way to use all the arguments of a given function when using a code template in NetBeans.
This really seems difficult. If you knew you will be using the macro when you declare the function, you could use templates like this:
// shortcut dsmfun1
function ${FUNCTION_NAME}($$${PAR1}) {
dsm($$${PAR1}, '$$${PAR1} in ' . __FUNCTION__ . '()');
${selection}${cursor}
}
...
// shortcut dsmfun4
function ${FUNCTION_NAME}($$${PAR1}, $$${PAR2}, $$${PAR3}, $$${PAR4}) {
dsm($$${PAR1}, '$$${PAR1} in ' . __FUNCTION__ . '()');
dsm($$${PAR2}, '$$${PAR2} in ' . __FUNCTION__ . '()');
dsm($$${PAR3}, '$$${PAR3} in ' . __FUNCTION__ . '()');
dsm($$${PAR4}, '$$${PAR4} in ' . __FUNCTION__ . '()');
${selection}${cursor}
}
Couple templates give you really quick declaration and you have to type the parameters' names only once.
If you are adding these macros later, you might want to have a look at this doc and implement your desired behavior (even though that might be quite tricky).
Hope this helps!
Why don't you just use get_defined_vars() to pass them all in one shot? This way, your macro only needs to be a single static line.
function dsm($func, array $args)
{
foreach ($args as $name => $value) {
echo "in $func, arg '$name' is $value\n";
}
}
function testModule_theme($existing, $type, $theme, $path) {
dsm(__FUNCTION__, get_defined_vars());
}
testModule_theme(1, 2, 3, 4);
Output:
in testModule_theme, arg 'existing' is 1
in testModule_theme, arg 'type' is 2
in testModule_theme, arg 'theme' is 3
in testModule_theme, arg 'path' is 4
I'm currently using the following method to get coordinates from GoogleMaps.
Can I possibly write this shorter/more efficient?
EDIT 21.06.2013
As of now the old Google Geocoding API is off. This is my modified code that works with the most recent version. I've updated this post, if someone stumbles over it and finds it useful.
public function getGeographicCoordinatesFromGoogle()
{
// create address string
$value = $this->address_line_1 . ' ' .
$this->postal_code . ' ' .
$this->city . ' ' .
$this->country;
$value = preg_replace('!\s+!', '+', $value);
// create request
$request = 'http://maps.googleapis.com/maps/api/geocode/xml?address=' .
$value . '&sensor=false';
// get value from xml request
$xml = file_get_contents($request);
$doc = new \DOMDocument('1.0', 'UTF-8');
#$doc->loadXML($xml);
// fetch result
$result = $doc->getElementsByTagName('lat')->item(0)->nodeValue . ',' .
$doc->getElementsByTagName('lng')->item(0)->nodeValue;
// check result
if (!preg_match('/(-?\d+\.\d+),(-?\d+\.\d+)/', $result) ) {
$result = null;
}
// assign value
$this->setGeographicCoordinates($result);
}
You can use json instead of xml. json is newer, lightweight and object orientated.
I'll recommend you to use http_build_query() instead of trying to build the SearchQuery with Regex. There are other chars which need to be escaped.
This is a quite long method. Maybe it would make sense to have one Class which only handles the communication with GoogleMaps (Class GeoBackend with methods getGeoDataForAddress(), which returns a GeoData-Object, which could be asked for Cordinates etc.)