I'm developing my first application in Codeigniter 2.0.2, and I've got a minor issue I can't seem to find any info about on the web.
The application revolves around resources stored locally on the server (namely images and audio files) which need to be exposed to the user. The locations of these resources are stored in a DB as absolute paths. As a result, I find myself needing to translate server paths to base_url-based URLs fairly often.
I already wrote a simple and robust-enough function to handle it for me, but with all the seemingly-relevant helpers in CI (url, path), I can't shake the feeling that I just reinvented the wheel.
At the least, I would think there would be some kind of CI function (say, "basify") that will translate any server path to a base_url-relative path like so:
$server_path = '/server/path/to/app/resources/image.jpg';
basify( $server_path ); // returns 'resources/image.jpg' or './resources/image.jpg'
where the CI app lives in /server/path/to/app. Then it's a simple call to base_url() to make the URL.
Does anything like that exist?
Edit: And yes, I know that a simple preg_replace will handle most cases for me (at least those where the resource is within the base path), but I feel like this should be CI's job, not mine! Half the reason I'm using it is because I don't want to think about path management.
Maybe you can use php function str_replace together with codeigniter FCPATH constant.
Your code will be:
function basify($image_path) {
return str_replace(FCPATH, '', $image_path);
}
The FCPATH constant is new to me, but I have done some tests and it works fine.
Related
I am developing a Clojure/ClojureScript SPA based on http-kit, compojure and tiny bits of hiccup on backend and mainly reagent on frontend. Project is done with leiningen, based on hand-wrecked chestnut template.
When I tried to make more complex URLs than just "/" the following setup created a mess for me:
When producing the initial hiccup to serve HTML and adding includes for CSS and JS files I followed the examples and added them as relative urls like
(include-css "css/style.css")
;and
(include-js "js/compiled/out/goog/base.js")
(include-js "js/compiled/myproject.js")
(note absence of slash in the beginning)
In the chestnut template I got default :asset-path option for cljsbuild set to "js/compiled/out"
Of course, when I tried to add a route to the same page with the http://my-domain/something URL in addition to root http://my-domain/ and load it, the thing failed to get any of my assets (trying to fetch them under e.g. /something/js/compiled/myproject.js).
I was able to fix this issue for explicitly included assets by making those urls relative to root (prepending a slash to each of them). It left me with the same problem with the script tag with src="js/compiled/out/cljs_deps.js" injected by cljsbuild, but this one I fixed by making :asset-path relative to root as well.
It all seems to work properly now, but the fact that I had to make some head-scratching and a surprisingly large amount of googling to finally resolve this makes me feel this is not the default approach. Hence the questions:
Did I do the right thing by converting all asset urls to relative-to-root ones? (Keeping in mind that I'm working on an SPA)
If yes, why isn't this a default approach and why I keep seeing relative-to-current location URLs everywhere (including all the examples on the web as well as lein templates)?
Update:
The relevant part of my app's compojure routes looks like this:
(defroutes home-routes
(resources "/")
(GET "/" _
(friend/authenticated
(html-response
(app-page))))
(GET "/something*" _
(friend/authenticated
(html-response
(app-page)))))
I'm trying to use phpBB3 (forum app) along with ZF2. For that, I have to include a file from the phpBB3. In theory this is as simple as:
include('/path/to/phpbb3/common.php');
$user->session_begin(); //$user is defined in common.php file
In common.php a lot of globals are defined, and after that are required some files which are using those globals.
In ZF2 simply including the common.php would not work, because the scope of the globals will not span over the required files, so I tried a little trick:
//in Application/Forum/Service
public function callForumAPI(){
$zf_dir = getcwd();
chdir('/var/www/html/phpBB3');
include('common.php');
$user->session_begin();
chdir($zf_dir);
}
Neither in this case the scope of the global variables didn't span over the required files, so all the globals where NULL in those files.
How could I solve this issue?
I consider 2 main problems:
1. Loading resources
I dont know if you changed the code of phpBB3, since if you dont, your problem is other.
Phpbb3, as many systems, doesnt let you access directly to any file, you have to go through index.php. As you can see in common.php
if (!defined('IN_PHPBB'))
{
exit;
}
IN_PHPBB is defined in index.php, so you can simply use
Also, common.php and other files, makes use of $phpbb_root_path, that is defined in index.php.
So, at least, when you are going to include common.php you need
$zf_dir = getcwd();
chdir('/var/www/html/phpBB3');
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
include('common.php');
...
chdir($zf_dir);
probably there are some other things you have to take care about.
2. Variable scopes
Also, consider than in PHP, like in almost every language, a variable declared inside a function, is considered local, and will be undefined outside that function. So for sure, if you do that inside callForumAPI(), you wont have any variable outside, and moreover, depending on where you are doing that includes...it could be actually inside a function, no matter you can notice it or not, since ZF2 is a framenwork with a complex, non-obvius architecture.
So, what i recomend, as soon as you load the file, is to use the ZF2 service manager to store all the variables and object than you would use in your application. This is a good measure even if you didnt need it,since this way you can have everything integrated as much as possible, it is important to minimize and localize access to phpbb3, since it is not meant to be a library, maintenance could be tricky, so if everyhing is in the same file, and then you create your own internal api through the service manager, it will more encapsulated and nicer. I assume you already know how to do this, if you dont, just let me know.
try this, and tell me if its enough or we need more research
I'm currently mapping my ZF1 applications to ZF2 and was wondering if there is a similar function like $this->view->getScriptPath() from ZF1 in ZF2? I spend already my half day, but didn't find a good solution. It would also be fine to get at least the basePath of the Module or the template folder of the Module.
Based on the follow-up questions, what you are really looking for is the path to a given template file. This is actually relatively easy, assuming you're using the default PhpRenderer: you grab the resolver, and resolve the path.
If you're inside a view script already, the following should work:
$path = $this->resolver($templateName);
If you're elsewhere, you need access to either the PhpRenderer, or the ViewResolver. If you have access to the service manager, pull the ViewResolver service, and call resolve() on it:
$resolver = $services->get('ViewResolver');
$path = $resolver->resolve($templateName);
This is superior to knowing where the module lives, as the developer may have chosen to override the template within the application; the resolver will know where even the new location is.
I am trying to display some Images which are in my local folder. I am getting the image name from a server through JSON. Based on that, I am constructing the Image path dynamically. However, the final image path will be changed by SC build tools. I know that we can use sc_static() in css or view's specifications to map it to the final path. How can I achieve that mapping (to final path from local path) while programmatically constructing my url.
Any ideas, suggestions and thoughts?
sc_static is not a javascript function, but rather a convention used to tell Abbot (Sproutcore's build tool, written in ruby) to replace it at runtime with a path pointing to the resource passed as first argument to sc_static.
Note that this substitution is done by Abbot when the page is refreshed (in dev mode) or when the app is built (in prod mode). It is not a js function at all (use Chrome inspector to see it by yourself).
If you want to use sc_static in JS you can define all resource references as such:
YourApp.loadingIcon=sc_static('loading.png');
YourApp.greenIcon=sc_static('green.png');
and then reference the
YourApp.loadingIcon , YourApp.greenIcon
variables in your code.
Finally I found the answer with the help of my friends. sc_static is not javascript function it is a function targeted for build tools(Abbot) of Sproutcore to replace the actual production path after build. Hence we can not use sc_static in programming.
If we want similar function we have develop our own.
I'm using Rhino's context.evaluateString() to run some simple JavaScript from inside of Java. It's textbook right out of the Embedding Javascript guide:
String script = // simple logic
Context c = new ContextFactory().enterContext();
ScriptableObject scope = context.initStandardObjects();
Object o = context.evaluateString(scope, script, "myScript", 1, null);
ScriptableObject result = Context.jsToJava(o, ScriptableObject.class);
I'm not sure this is the current best-practice, because the main Rhino docs appear to be down, but it's working so far.
I'd like to be able to refer to a library in the working directory -- I see that Rhino shell supports load but I don't think this works in the embedding engine.
Is this possible? Is it documented anywhere? Ideally, I'd like to be able to just call something like load('other.js') and have it search directories I specify as a global property.
I have a sort-of answer that I don't really like, not least because it exposes what I'm pretty sure is a Rhino bug that drove me crazy for the last half hour:
eval("" + Packages.org.apache.commons.io.FileUtils.readFileToString(
new java.io.File("/the/local/root", "script.js");
));
{ That "" + ... is how I work around the bug -- if you eval() a Java String (such as is returned from the readFileToString call) without manually coercing it to a JavaScript native string, nothing appears to happen. The call just silently fails. }
This blindly reads an arbitrary file and evals it -- of course, this is what you do when you eval() from the Java side, so I don't worry about it too much.
Anyway, it's not elegant for a number of reasons, but it works. I'd love to hear a better answer!