I'm using the jquery address plugin to build an ajax driven site, and i've got it working! Yay! For the purposes of this question we can use the test site:
http://www.asual.com/jquery/address/samples/crawling
http://www.asual.com/download/jquery/address
(I had to remove two calls to urlencode() to make the crawling example work.)
I'm encountering a problem with the $crawling->nav() call. It basically uses js and php to load parts of an xml file into the dom. I (mostly) understand how it works, and I would like to modify the example code to include sub pages.
For example, I would like to show 'subnav-project.html' at '/!#/project' and '/!#/project/blue', but not at '/!#/contact'. To do this, I figure php should 'know' what page the user is on, that way I can base my logic off of that.
Is this crazy? Can php ever know the current state of the site if I'm building it this way? If not, how does one selectively load html snippets, or modify what links are shown in navigation menus?
I've never gotten too crazy with ajax before, so any feedback at all would be helpful.
EDIT
This is the crawling class.
class Crawling {
const fragment = '_escaped_fragment_';
function Crawling(){
// Initializes the fragment value
$fragment = (!isset($_REQUEST[self::fragment]) || $_REQUEST[self::fragment] == '') ? '/' : $_REQUEST[self::fragment];
// Parses parameters if any
$this->parameters = array();
$arr = explode('?', $fragment);
if (count($arr) > 1) {
parse_str($arr[1], $this->parameters);
}
// Adds support for both /name and /?page=name
if (isset($this->parameters['page'])) {
$this->page = '/?page=' . $this->parameters['page'];
} else {
$this->page = $arr[0];
}
// Loads the data file
$this->doc = new DOMDocument();
$this->doc->load('data.xml');
$this->xp = new DOMXPath($this->doc);
$this->nodes = $this->xp->query('/data/page');
$this->node = $this->xp->query('/data/page[#href="' . $this->page . '"]')->item(0);
if (!isset($this->node)) {
header("HTTP/1.0 404 Not Found");
}
}
function base() {
$arr = explode('?', $_SERVER['REQUEST_URI']);
return $arr[0] != '/' ? preg_replace('/\/$/', '', $arr[0]) : $arr[0];
}
function title() {
if (isset($this->node)) {
$title = $this->node->getAttribute('title');
} else {
$title = 'Page not found';
}
echo($title);
}
function nav() {
$str = '';
// Prepares the navigation links
foreach ($this->nodes as $node) {
$href = $node->getAttribute('href');
$title = $node->getAttribute('title');
$str .= '<li><a href="' . $this->base() . ($href == '/' ? '' : '?' . self::fragment . '=' .html_entity_decode($href)) . '"'
. ($this->page == $href ? ' class="selected"' : '') . '>'
. $title . '</a></li>';
}
echo($str);
}
function content() {
$str = '';
// Prepares the content with support for a simple "More..." link
if (isset($this->node)) {
foreach ($this->node->childNodes as $node) {
if (!isset($this->parameters['more']) && $node->nodeType == XML_COMMENT_NODE && $node->nodeValue == ' page break ') {
$str .= '<p><a href="' . $this->page .
(count($this->parameters) == 0 ? '?' : '&') . 'more=true' . '">More...</a></p>';
break;
} else {
$str .= $this->doc->saveXML($node);
}
}
} else {
$str .= '<p>Page not found.</p>';
}
echo(preg_replace_callback('/href="(\/[^"]+|\/)"/', array(get_class($this), 'callback'), $str));
}
private function callback($m) {
return 'href="' . ($m[1] == '/' ? $this->base() : ($this->base() . '?' . self::fragment . '=' .$m[1])) . '"';
}
}
$crawling = new Crawling();
You won't be able to make server-side decisions using the fragment-identifier (i.e., everything to the right of the # character). This is because browsers don't send fragment-identifiers to the server. If you're going to want to make server-side decisions, you'll need to use some JavaScript assistance (including AJAX) to communicate what the current fragment-identifier is.
Related
This question already has answers here:
Multiple returns from a function
(32 answers)
Closed 2 years ago.
I have the script below and I need to return both of the conditional return values -- each result on a line. Is there any way to format it as an array in order to work ?
The script is:
if ($pdf_url != '') {
if ($title != '') {
$title_from_url = $this->make_title_from_url($pdf_url);
if ($title == $title_from_url || $this->make_title_from_url('/'.$title) == $title_from_url) {
// This would be the default title anyway based on URL
// OR if you take .pdf off title it would match, so that's close enough - don't load up shortcode with title param
$title = '';
} else {
$title = ' title="' . esc_attr( $title ) . '"';
}
}
return apply_filters('pdfemb_override_send_to_editor', '[pdf-embedder url="' . $pdf_url . '"'.$title.']', $html, $id, $attachment);
} else {
return $html;
}
If you want each result on a line, it sounds like you could use a temporary variable, and concatenate to it based on the logic.
<?php
$output = '';
if ($pdf_url != '') {
if ($title != '') {
$title_from_url = $this->make_title_from_url($pdf_url);
if ($title == $title_from_url || $this->make_title_from_url('/'.$title) == $title_from_url) {
// This would be the default title anyway based on URL
// OR if you take .pdf off title it would match, so that's close enough - don't load up shortcode with title param
$title = '';
} else {
$title = ' title="' . esc_attr( $title ) . '"';
}
}
// You may need print_r() around apply_filters() if it returns an array
$output .= apply_filters('pdfemb_override_send_to_editor', '[pdf-embedder url="' . $pdf_url . '"'.$title.']', $html, $id, $attachment) . "\n";
} else {
$output .= $html . "\n";
}
return $output;
Or if you want it in array:
<?php
$output = [];
if ($pdf_url != '') {
if ($title != '') {
$title_from_url = $this->make_title_from_url($pdf_url);
if ($title == $title_from_url || $this->make_title_from_url('/'.$title) == $title_from_url) {
// This would be the default title anyway based on URL
// OR if you take .pdf off title it would match, so that's close enough - don't load up shortcode with title param
$title = '';
} else {
$title = ' title="' . esc_attr( $title ) . '"';
}
}
// You may need print_r() around apply_filters() if it returns an array
$output[] = apply_filters('pdfemb_override_send_to_editor', '[pdf-embedder url="' . $pdf_url . '"'.$title.']', $html, $id, $attachment);
} else {
$output[] = $html;
}
return $output;
So I'm trying to make a website, and I'm using a php file as the index (index.php) and pretty much as the page that controls the whole website.
Since it recieves all the requests and returns the pages using str_replace, it's all working as it should (as in, it's making the web template work as it should) but the problem is I can't have php code inside the files that are part of the template, only in index.php.
So my question is, is there any way to prevent str_replace from turning the php code into comments?
Index.php:
<?php
//dirs
$pagesDir = "pages/";
$templatesDir = "templates/";
$errorsDir = "errors/";
if (isset($_REQUEST['page'])) {
if ($_REQUEST['page'] != "")
if (file_exists($pagesDir . $_REQUEST['page'] . ".html"))
$page_content = file_get_contents($pagesDir . $_REQUEST['page'] . ".html");
else
if (file_exists($_REQUEST['page'] . ".html"))
$page_content = file_get_contents($_REQUEST['pages'] . ".html");
else
echo "<h1>Page:" . $_REQUEST['page'] . " does not exist! Please check the url and try again!</h1>";
} else {
$page_content = file_get_contents($pagesDir . "home.html");
}
//PLACEHOLDER REPLACEMENT
$page_content = str_replace("!!HEAD!!", file_get_contents($templatesDir . "head.html"), $page_content);
$page_content = str_replace("!!BODY!!", file_get_contents($templatesDir . "body.html"), $page_content);
$page_content = str_replace("!!FOOT!!", file_get_contents($templatesDir . "eofScripts.html"), $page_content);
//RETURN THE CONTENT OF THE PAGE
echo $page_content;
New dispatcher after changes(this one works):
<?php
$templatesDir = "templates/";
$pagesDir = "pages/";
$loggedPagesDir = "templates/logged";
$pageExists = false;
$pageContent = null;
require_once('scripts/php/db_conn.php');
if (isset($_REQUEST['page'])) {
$page = $_REQUEST['page'] . ".php";
}
if (isset($_SESSION['redirect_reason'])) {
$dialogs->alertDialog("warningDialog", $_SESSION['redirect_reason']);
unset($_SESSION['redirect_reason']);
}
if (isset($_SESSION['user_action'])) {
$dialogs->alertDialog("infoDialog", $_SESSION['user_action']);
unset($_SESSION['user_action']);
}
if ($user->is_logged()) { //Only runs beyond this point if user is logged, if not, it will run the other one.
if (isset($_POST['logout_btn'])) {
$user->logout();
$user->redirect("pageDispatcher.php");
}
if (isset($page)) {
if ($page != "") {
if (file_exists($pagesDir . $page)) {
$pageExists = true;
$pageContent = ($pagesDir . $page);
} else {
echo "<h1>Page: " . $page . "does not exist! Please check the url and try again</h1>";
}
} else {
$pageExists = true;
$pageContent = ($pagesDir . "loggedhome.php");
}
} else {
$pageExists = true;
$pageContent = ($pagesDir . "loggedhome.php");
}
} else { //Only runs beyond this point if user isn't logged.
if (isset($_POST['login_btn'])) {
if ($user->login($_POST['email'], $_POST['password']) == false) {
$dialogs->loginFailed();
} else {
$_SESSION['user_action'] = "Welcome back " . $_SESSION['user_name'];
$user->redirect("pageDispatcher.php");
}
}
if (isset($page)) {
if ($page != "") {
if (file_exists($pagesDir . $page)) {
$pageExists = true;
$pageContent = ($pagesDir . $page);
} else {
echo "<h1>Page: " . $page . " does not exist! Please check the url and try again!</h1>";
}
} else {
$pageExists = true;
$pageContent = ($pagesDir . "home.php");
}
} else {
$pageExists = true;
$pageContent = ($pagesDir . "home.php");
}
}
?>
<html>
<?php include($templatesDir . "head.html"); ?>
<body>
<?php
if ($user->is_logged()) {
include($templatesDir . "loggedBody.html");
} else {
include($templatesDir . "body.html");
}
include($pageContent);
?>
</body>
</html>
NOTE: Do not use this method unless it's for learning purposes, its bad, can turn out to be quite hard to maintain, and probably will end up being slow since I have so many server side methods of things that I can do client side.
You read the content of page and echo it! Don't do that. Use include('file.html') instead. Just for sake of explanation, (if you have to) do sth like this:
$pages=['head.html','body.html','eofScripts.html'];
$page=$_REQUEST['page'];
if(in_array($page,$pages)) include($page);
else echo "<h1>Page: $page does not exist!</h1>";
But generally this is bad programming practice. As suggested in comments before do use a template engine.
I need create a function that checks a parsed value to see if it matches a few other values and then return that match. For example I am trying to match video urls correctly. So if it's youtube do this or if it's vimeo do this or if it's nothing do this. I know how to create a function but I'm not sure what to use for the parse, would it be parse_url?
For my test cases I need to send in the right parameter and then see that the returned values are matching what I want them to be.
Here's what I've tried so far:
function get_video_embed_string($videostring) {
$video_url_parse = parse_url( $videostring, PHP_URL_HOST ); //get the input string ready to parse
$returnstring = ""; //default return string to empty string
if ($video_url_parse === 'vimeo.com') {
$returnstring = str_replace( 'vimeo.com', 'player.vimeo.com', $video_url_parse );
} else if ($video_url_parse === 'youtube.com') {
$returnstring = str_replace( 'youtube.com', 'youtube.com/embed/', $video_url_parse );
} else {
//do nothing
}
return $returnstring;
}
parse_str($returnstring);
//now setup your test cases and see what echos out of the above method
if ($returnstring === 'player.vimeo.com') {
echo "vimeo: <" . get_video_embed_string ("https://vimeo.com/abcdefg123") . ">";
} else if ($returnstring === 'youtube.com/embed/'){
echo "youtube: <" . get_video_embed_string ("https://youtube.com/abcdefg123") . ">";
} else if($returnstring === '' ){
echo "nothing: <" . get_video_embed_string ("https://abc123.com/abcdefg123") . ">";
} else {
echo "empty:< " . get_video_embed_string ("") . ">";
}
I think you're on the right track using parse_url, but I have a couple suggestions for improvement:
instead of the run-on if/elseif chain, use a switch
the str_replace isn't working well as is because you're replacing the parsed host, so why spend the overhead searching again for the string to replace when you've already found it.
in the user comments for parse_url, there's an excellent example to reconstruct the parsed url. this will avoid string replacements where the host name is also part of the url (www.youtube.com/youtubevideo123)
simplify your test cases by just calling your function for each case instead of another if/else chain check.
function get_video_embed_string($videostring) {
$video_url_parse = parse_url($videostring); //get the input string ready to parse
switch ($video_url_parse['host']) {
case 'vimeo.com':
$video_url_parse['host'] = 'player.vimeo.com';
return unparse_url($video_url_parse);
case 'youtube.com':
$video_url_parse['host'] = 'youtube.com/embed';
return unparse_url($video_url_parse);
default:
return unparse_url($video_url_parse);
}
}
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass#" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}
//now setup your test cases and see what echos out of the above method
echo "vimeo: <" . get_video_embed_string ("https://vimeo.com/abcdefg123") . ">\n";
echo "youtube: <" . get_video_embed_string ("https://youtube.com/abcdefg123") . ">\n";
echo "nothing: <" . get_video_embed_string ("https://abc123.com/abcdefg123") . ">\n";
echo "empty:< " . get_video_embed_string ("") . ">\n";
This will result in the following output in source:
vimeo: <https://player.vimeo.com/abcdefg123>
youtube: <https://youtube.com/embed/abcdefg123>
nothing: <https://abc123.com/abcdefg123>
empty:< >
parse_url() is very good for parsing URLs and - in your case - extract the host name from it.
Your example is a little messed up. $returnstring is not defined outside of your function. You should turn error reporting on, so you will see NOTICE messages on this kind of errors.
I assume, your function should return the video embed url, not only the host name. So you should do your replace on $videostring, not $video_url_parse:
function get_video_embed_string($videostring) {
$video_url_parse = parse_url( $videostring, PHP_URL_HOST ); //get the input string ready to parse
$returnstring = ""; //default return string to empty string
if ($video_url_parse === 'vimeo.com') {
$returnstring = str_replace( 'vimeo.com', 'player.vimeo.com', $videostring );
} else if ($video_url_parse === 'youtube.com') {
$returnstring = str_replace( 'youtube.com', 'youtube.com/embed', $videostring );
} else {
//do nothing
}
return $returnstring;
}
This will give you this output:
echo get_video_embed_string("https://vimeo.com/abcdefg123"); // https://player.vimeo.com/abcdefg123
echo get_video_embed_string("https://youtube.com/abcdefg123"); // https://youtube.com/embed/abcdefg123
echo get_video_embed_string("https://abc123.com/abcdefg123"); // <empty string>
[For a more robust approach, I would probably try to extract the video ID from all known valid URL schemes using regexp and just insert this ID in the embed url.]
I am about to make a system that automaticly puts &pni=something behind an URL. It would be easy if the url just was http://t.co/something.php with "?pni=...." but users can also have http://t.co/something.php?myown=paramater and then the system should add & instead of ?
How can I put the pni parameter behind the URL and to be valid every time? I've tried this without luck.
<?php
function nice($in){
$out = parse_url($in);
return $out['scheme'] . "://" . $out['host'] . $out['path'] . "?" . $out['query'];
}
$urls = array(
"http://t.co/something.php?w=23&",
"http://t.co/something.php?w=23&dfdf=",
"http://t.co/something.php?",
"http://t.co/something.php",
"http://t.co/something",
"http://t.co/something.php?w=23&dfdf=34&hvem",
);
foreach ( $urls as $url):
echo print_r(nice($url)) . "<br/>";
endforeach;
?>
function nice($in) {
$out = parse_url($in);
if ($out['query'] != "") {
$out['query'] = "pni=something&".$out['query'];
}
else {
$out['query'] = "pni=something";
}
return $out['scheme'] . "://" . $out['host'] . $out['path'] . "?" . $out['query'];
}
check if there is any "?" in the url and concat the pni=something to it accordingly.
function nice($url){
if(strpos($url,"?")!==false){
return $url."&pni=something";
}else{
return $url."?pni=something";
}
}
You can access the query string specifically using
$_SERVER['QUERY_STRING']
If it is empty you can use
$url .= '?arg=val';
If query string is ! empty
$url .= '&arg=val';
I need a form to autolink links that users input in text fields. I found an example on stack which works perfectly, except for one thing. if the user inputs a link without including http:// or https:// and instead starts the link only using www. the link does not work properly.
ie a user input would be
check out our twitter!
www.twitter.com/#!/profile
and our facebook!
https://www.facebook.com/profile
the output would be
check out our twitter!
www.twitter.com/#!/profile
and our facebook!
http://www.facebook.com/profile
so the facebook link works perfectly, but the twitter one would not, as its being linked to the current location the user is on plus the new link, ie if they are currently on www.example.com the link would become www.example.com/www.twitter.com/#!/profile
for the life of me, i cant figure out how to fix this by simply adding http:// to the beginning of the link, this is the function:
function auto_link_text($text) {
$pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
return preg_replace_callback($pattern, 'auto_link_text_callback', $text);
}
function auto_link_text_callback($matches) {
$max_url_length = 50;
$max_depth_if_over_length = 2;
$ellipsis = '…';
$url_full = $matches[0];
$url_short = '';
if (strlen($url_full) > $max_url_length) {
$parts = parse_url($url_full);
$url_short = $parts['scheme'] . '://' . preg_replace('/^www\./', '', $parts['host']) . '/';
$path_components = explode('/', trim($parts['path'], '/'));
foreach ($path_components as $dir) {
$url_string_components[] = $dir . '/';
}
if (!empty($parts['query'])) {
$url_string_components[] = '?' . $parts['query'];
}
if (!empty($parts['fragment'])) {
$url_string_components[] = '#' . $parts['fragment'];
}
for ($k = 0; $k < count($url_string_components); $k++) {
$curr_component = $url_string_components[$k];
if ($k >= $max_depth_if_over_length || strlen($url_short) + strlen($curr_component) > $max_url_length) {
if ($k == 0 && strlen($url_short) < $max_url_length) {
// Always show a portion of first directory
$url_short .= substr($curr_component, 0, $max_url_length - strlen($url_short));
}
$url_short .= $ellipsis;
break;
}
$url_short .= $curr_component;
}
} else {
$url_short = $url_full;
}
return "<a rel=\"nofollow\" href=\"$url_full\">$url_short</a>";
}
Use strpos function.
if the input contains "http://" forward directly. Otherwise add it direct it.