Wordpress functions - get values without echo - php

How can I programmatically use the data of the bult-in Wordpress functions.
E.g. I'd like to use the data of
the_author_meta('login_name');
in a php function. Problem: The function echoes the value by default. In order to use the actual value in a function I can think of using an output buffer like ...
ob_start();
the_author_meta('login_name');
$contents = ob_get_contents();
ob_end_clean();
but I was hoping for a better (less bloated) solution.
Any idea how to get the echo values as simple return values instead?

use get_the_author_meta() for return the value.
Note: All of wordpress meta methods (the_post,the_author,the_page etc.) are supports the get_ prefix

Related

How to make dynamic links in php without eval()

I am using wordpress for a web site. I am using snippets (my own custom php code) to fetch data from a database and echo that data onto my web site.
if($_GET['commentID'] && is_numeric($_GET['commentID'])){
$comment_id=$_GET['commentID'];
$sql="SELECT comments FROM database WHERE commentID=$comment_id";
$result=$database->get_results($sql);
echo "<dl><dt>Comments:</dt>";
foreach($result as $item):
echo "<dd>".$item->comment."</dd>";
endforeach;
echo "</dl>";
}
This specific page reads an ID from the URL and shows all comments related to that ID. In most cases, these comments are texts. But some comments should be able to point to other pages on my web site.
For example, I would like to be able to input into the comment-field in the database:
This is a magnificent comment. You should also check out this other section for more information
where getURLtoSectionPage() is a function I have declared in my functions.php to provide the static URLs to each section of my home page in order to prevent broken links if I change my URL pattern in the future.
I do not want to do this by using eval(), and I have not been able to accomplish this by using output buffers either. I would be grateful for any hints as to how I can get this working as safely and cleanly as possible. I do not wish to execute any custom php code, only make function calls to my already existing functions which validates input parameters.
Update:
Thanks for your replies. I have been thinking of this problem a lot, and spent the evening experimenting, and I have come up with the following solution.
My SQL "shortcode":
This is a magnificent comment. You should also check out this other section for more information
My php snippet in wordpress:
ob_start();
// All my code that echo content to my page comes here
// Retrieve ID from url
// Echo all page contents
// Finished generating page contents
$entire_page=ob_get_clean();
replaceInternalLinks($entire_page);
PHP function in my functions.php in wordpress
if(!function_exists("replaceInternalLinks")){
function replaceInternalLinks($reference){
mb_ereg_search_init($reference,"\[custom_func:([^\]]*):([^\]]*)\]");
if(mb_ereg_search()){
$matches = mb_ereg_search_getregs(); //get first result
do{
if($matches[1]=="getURLtoSectionPage" && is_numeric($matches[2])){
$reference=str_replace($matches[0],getURLtoSectionPage($matches[2]),$reference);
}else{
echo "Help! An unvalid function has been inserted into my tables. Have I been hacked?";
}
$matches = mb_ereg_search_regs();//get next result
}while($matches);
}
echo $reference;
}
}
This way I can decide which functions it is possible to call via the shortcode format and can validate that only integer references can be used.
I am safe now?
Don't store the code in the database, store the ID, then process it when you need to. BTW, I'm assuming you really need it to be dynamic, and you can't just store the final URL.
So, I'd change your example comment-field text to something like:
This is a magnificent comment. You should also check out this other section for more information
Then, when you need to display that text, do something like a regular expression search-replace on 'href="#comment-([0-9]+)"', calling your getURLtoSectionPage() function at that point.
Does that make sense?
I do not want to do this by using eval(), and I have not been able to accomplish this by using output buffers either. I would be grateful for any hints as to how I can get this working as safely and cleanly as possible. I do not wish to execute any custom php code, only make function calls to my already existing functions which validates input parameters.
Eval is a terrible approach, as is allowing people to submit raw PHP at all. It's highly error-prone and the results of an error could be catastrophic (and that's without even considering the possibly that code designed by a malicious attacker gets submitted).
You need to use something custom. Possibly something inspired by BBCode.

wordpress style shortcodes in Ckeditor / PHP

I have built a custom CMS. Recently, I added the ability to create pages dynamically. I used CKEditor for the content of these pages.
I would also like to run some php functions that may be included in the content of the page stored in mysql.
I DO NOT want to store actual PHP code in the database, but rather function names perhaps. For example, in a page stored in the database I may have.
<?php //begin output
hello world!
check out this latest news article.
news($type, $id);
//end output
?>
What is the best way to find and execute this existing function without using EVAL if its found in the output? I was thinking along the lines of wordpress style short codes. Maybe [[news(latest, 71]] ? Then have a function to find and execute these functions if they exist in my functions.php file. Not really sure the best way to go about this.
I'm not searching for any code answers, but more of a best practice for this type of scenario, especially one that is safest against possible injections.
I found a solution from digging around and finding this thread
How to create a Wordpress shortcode-style function in PHP
I am able to pass short codes like this in CKEditor
[[utube 1 video_id]]
Then, in my page that renders the code:
print shortcodify($page_content);
using this function:
function shortcodify($string){
return preg_replace_callback('#\[\[(.*?)\]\]#', function ($matches) {
$whitespace_explode = explode(" ", $matches[1]);
$fnName = array_shift($whitespace_explode);
return function_exists($fnName) ? call_user_func_array($fnName,$whitespace_explode) : $matches[0];
}, $string);
}
If the function name exist (utube) it will fire the function.
Only problem Im having at the moment is not matter where I place the [[shortcode]] in my editor, it always executes first.
For example, in CKEditor I put:
Hello world! Check out my latest video
[[utube 1 video_id]]
It will always put the text under the video instead of where it is in the document. I need to figure a way to have the short code execute in the order it is placed.

Suppress echo from PHP include file

I have a file PHP01.php which:
- performs a function
- creates an array
- echo's some message
I need to include this file in another php script, say PHP02.php as I need access to the array it created. But when I jquery POST request to PHP02.php, the data it returns also has the echo from PHP01.php
How can I suppress the echo from the first file?
You can output buffer it if editing or otherwise restructuring is not possible:
ob_start();
include "PHP02.php";
ob_end_clean();
If you can, you should look at refactoring the code in the original PHP file. If it's performing a function, it should do that. Then, the code that called the function should decide if they want to echo a message.
As you've just learned, this is an important part of orthogonal design. I'd recommend re-writing it so that it performs what you want it to, and let the code that calls the function, decide what they want to output. That way you won't have to worry about these things again.
You can also look into using output buffers. See ob_flush in PHP: http://php.net/manual/en/function.ob-flush.php
Try adding a conditional to PHP01.php that checks to see where it is being called from, this will ensure that you only echo it out if the file making the call is PHP01.php
Additionally it is better if you place functions in their own file to be included if needed so as to keep certain features that are present from being included for example in PHP01.php you can add include 'function01.php'; and it will have that function shared across the two files.
create a new function without the echo

How to cache code in PHP?

I am creating a custom form building system, which includes various tokens. These tokens are found using Regular Expressions, and depending on the type of toke, parsed. Some require simple replacement, some require cycles, and so forth.
Now I know, that RegExp is quite resource and time consuming, so I would like to be able to parse the code for the form once, creating a php code, and then save the PHP code, for next uses. How would I go about doing this?
So far I have only seen output caching. Is there a way to cache commands like echo and cycles like foreach()?
Because of misunderstandings, I'll create an example.
Unparsed template data:
Thank You for Your interest, [*Title*] [*Firstname*] [*Lastname*]. Here are the details of Your order!
[*KeyValuePairs*]
Here is the link to Your request: [*LinkToRequest*].
Parsed template:
"Thank You for Your interest, <?php echo $data->title;?> <?php echo $data->firstname;?> <?php echo $data->lastname;?>. Here are the details of Your order!
<?php foreach($data->values as $key=>$value){
echo $key."-".$value
}?>
Here is the link to Your request: <?php echo $data->linkToRequest;?>.
I would then save the parsed template, and instead of parsing the template every time, just pass the $data variable to the already parsed one, which would generate an output.
You simply generate the included file, you save it in a non-publicly accessible folder, and you include inside a PHP function using include($filename);
A code example:
function render( $___template, $___data_array = array() )
{
ob_start();
extract( $___data_array );
include ( $___template);
$output = ob_get_clean();
echo $output;
}
$data = array('Title' => 'My title', 'FirstName' => 'John');
render('templates/mytemplate.php', $data);
Note the key point is using extract ( http://php.net/extract ) to expand the array contents in real vars.
(inside the scope of the function $___data['FirstName'] becomes $FirstName)
UPDATE: this is, roughly, the method used by Wordpress, CodeIgniter and other frameworks to load their PHP based templates.
I'm not sure if understood your problem, but did you try using APC?
With APC you could cache variables so if you echo a specific variable, you could get it from cache.
You do all your calculations, save the information in some variables, and save those variables in the cache. Then, next time you just fetch that information from cache.
It's really easy to use APC. You just have to call apc_fetch($key) to fetch, and apc_store($key, $value, $howLongYouWant2Cache) to save it.
You best bet would to simply generate a PHP file and save it. I.e.,
$replacement = 'foobar';
$phpCodeTemplate = "<?php echo '$replacement'; ?>";
file_put_contents('some_unique_file_name.php', $phpCodeTemplate);
Just be very careful when dynamically generating PHP files, as you don't want to allow users to manipulate data to include anything malicious.
Then, in your process, simply check if the file exists, is so, run it, otherwise, generate the file.

Best way to get post info into variables without displaying them in Wordpress

I am writing a Wordpress plugin and need to go through a number of posts, grab the data from them (for the most part title, permalink, and content), and apply processing to them without displaying them on the page.
What I've looked at:
I've looked at get_posts() for getting the posts, and then
getting title via the_title(),
content via the_content(),
and permalink via the_permalink()
Keep in mind that I need this data after all filters had already been applied, so that I get the exact data that would be displayed to the user. Each of the functions above seems to apply all necessary filters and do some postprocessing already, which is great.
The Problem:
The problem is all these functions, at least in WP 2.7.1 (latest released version right now) by default just echo everything and don't even return anything back. the_title() actually supports a flag that says do not print and return instead, like so
the_title(null, null, false)
The other 2, however, don't have such flags, and such inconsistency is quite shocking to me.
I've looked at what each of the_() functions does and tried to pull this code out so that I can call it without displaying the data (this is a hack in my book, as the behavior of the_() functions can change at any time). This worked for permalink but for some reason get_the_content() returns NULL. There has to be a better way anyway, I believe.
So, what is the best way to pull out these values without printing them?
Some sample code
global $post;
$posts = get_posts(array('numberposts' => $limit));
foreach($posts as $post){
$title = the_title(null, null, false); // the_title() actually supports a "do not print" flag
$permalink = apply_filters('the_permalink', get_permalink()); // thanks, WP, for being so consistent in your functions - the_permalink() just prints /s
$content = apply_filters('the_content', get_the_content()); // this doesn't even work - get_the_content() returns NULL for me
print "<a href='$permalink'>$title</a><br>";
print htmlentities($content, ENT_COMPAT, "UTF-8"). "<br>";
}
P.S. I've also looked at What is the best method for creating your own Wordpress loops? and while it deals with an already obvious way to cycle through posts, the solution there just prints this data.
UPDATE: I've opened a ticket with Wordpress about this. http://core.trac.wordpress.org/ticket/9868
Most functions the_stuff() in WP that echo something have their get_the_stuff() counterpart that returns something.
Eg get_the_title(), get_permalink()...
If you can't find the exact way to do it, you can always use output buffering.
<?php
ob_start();
echo "World";
$world = ob_get_clean();
echo "Hello $world";
?>
OK, I got it all sorted now. Here is the final outcome, for whoever is interested:
Each post's data can be accessed via iterating through the array returned by get_posts(), but this data will just be whatever is in the database, without passing through any intermediate filters
The preferred way is to access data using get_the_ functions and them wrapping them in an call to apply_filters() with the appropriate filter. This way, all intermediate filters will be applied.
apply_filters('the_permalink', get_permalink())
the reason why get_the_content() was returning an empty string is that apparently a special call to setup_postdata($post); needs to be done first. Then get_the_content() returns data properly
Thanks everyone for suggestions.
Is there any reason you can't do your processing at the time each individual post is posted, or when it's being displayed?
WP plugins generally work on a single post at a time, so there are plenty of hooks for doing things that way.

Categories