Yii2 Path format recursive URL - url

I am not good at English so i will try to be as clear as possible:
I have a project in Yii2 that has an advanced template, in the database i have a recursive table that represents a tree of categories and entries, you can imagine it as a folder tree that can have unlimited docs and folders (a folder inside another folder is possible), i have created the url in this format;
localhost://my-project/root-category/sub-cat-A/sub-cat-B/25-document
i need tho get the last section of the current Url because, the entire Url can have N levels before the entry that is located in the last section of the Url in the format below:
<id:\d+>-<slug:[A-Za-z0-9-_.]+>
But i don't know about any Url rule that could resolve this.
Appreciate your answers.
Thank you.

I solved it by myself and i am going to tell you how to solve or if any of you can improve this answer:
i am using the codemix/yii2-localeurls extension, i means that i had to extend the codemix\localeurls\UrlManager class and overwrite the parseRequest method like this:
public function parseRequest( $request ) {
$pathInfo = $request->getPathInfo();
$matches = 0;
$has_matches = preg_match( '%(bussiness-lines|lineas-de-negocio)\/(.)+\/%', $pathInfo, $matches );
if ( $has_matches ) {
/*
* GET THE LAST SECTION FROM THE URL
*/
$explode_patInfo = explode( '/', $pathInfo );
$tree_element = end( $explode_patInfo );
/*
* SEPARATES THE ID AND THE SLUG FROM THE URL
*/
$tree_element_explode = explode( '-', $tree_element );
$tree_element_id = reset( $tree_element_explode );
unset( $tree_element_explode[0] );
$tree_element_slug = implode( '-', $tree_element_explode );
/*
* RETURN THE CONTROLLER/ACTION AND ITS PARAMS TO PROCESS THE REQUEST
*/
if ( $tree_element !== false ) {
return [
'site/get-tree-element',
[
'id' => $tree_element_id,
'slug' => $tree_element_slug
]
];
}
}
//IF THE REQUEST DOES NOT CORRESPOND TO MY CUSTOM URL RULE, LETS THE PARENT DO THE JOB
return parent::parseRequest( $request );
}
I am sharing this hoping that can help any of you guys.
Peace.

Related

Drools mode stream and containers

HI this is my code.
public static KieContainer createKieContainerForProject() {
KieServices ks = KieServices.Factory.get();
// Create a module model
KieModuleModel kieModuleModel = ks.newKieModuleModel();
// Base Model from the module model
KieBaseModel kieBaseModel = kieModuleModel.newKieBaseModel( "KBase" )
.setDefault( true )
.setEqualsBehavior( EqualityBehaviorOption.EQUALITY)
.setEventProcessingMode( EventProcessingOption.STREAM );
// Create session model for the Base Model
KieSessionModel ksessionModel = kieBaseModel.newKieSessionModel( "KSession" )
.setDefault( true )
.setType( KieSessionModel.KieSessionType.STATEFUL )
.setClockType( ClockTypeOption.get("realtime") );
// Create File System services
KieFileSystem kFileSystem = ks.newKieFileSystem();
File file = new File("src/main/resources/rules/Sample.drl");
Resource resource = ks.getResources().newFileSystemResource(file).setResourceType(ResourceType.DRL);
kFileSystem.write( resource );
KieBuilder kbuilder = ks.newKieBuilder( kFileSystem );
// kieModule is automatically deployed to KieRepository if successfully built.
kbuilder.buildAll();
if (kbuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {
throw new RuntimeException("Build time Errors: " + kbuilder.getResults().toString());
}
KieContainer kContainer = ks.newKieContainer(ks.getRepository().getDefaultReleaseId());
return kContainer;
}
}
it's dont work when I call the fucntion, and my rules no work too.
my rule is
rule "Sound the alarm in case temperature rises above threshold"
when
TemperatureThreshold( $max : max )
Number( doubleValue > $max ) from accumulate(
SensorReading( $temp : temperature ) over window:time( 10m ),
average( $temp ) )
then
// sound the alarm
end
when I run the program, He says it has error, mode not stream and the code dont work.
how do I put a program in stream mode?
REduce your code, and add -KieBase and KieSession creation:
KieServices ks = KieServices.Factory.get();
KieFileSystem kFileSystem = ks.newKieFileSystem();
FileInputStream fis = new FileInputStream( "...drl" );
kFileSystem.write("src/main/resources/somename.drl",
ks.getResources().newInputStreamResource( fis ) ); //XXX
KieBuilder kbuilder = ks.newKieBuilder( kFileSystem );
kbuilder.buildAll();
if (kbuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {
throw new RuntimeException("Build time Errors: " + kbuilder.getResults().toString());
}
KieContainer kContainer = ks.newKieContainer(ks.getRepository().getDefaultReleaseId());
KieBaseConfiguration config = ks.newKieBaseConfiguration();
config.setOption(EventProcessingOption.STREAM);
KieBase kieBase = kContainer.newKieBase( config );
KieSession kieSession = kieBase.newKieSession();
This should give you a session that's capable of running your rule. (
According to the docs, it's as follows:
KieBaseConfiguration config = KieServices.Factory.get().newKieBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
But it's probably worth taking a look at this Drools test for a working example.

Jquery mobile, How to use changePage to update changeHash and Parameters

options.dataUrl = urlObj.href;
$.mobile.changePage( $page, options );
dataUrl contains the complete url with parameters
http://example.com/#sales?p=page
but the above code only updates the url with hash only, after the new page loads... the url changes to
http://example.com/#sales
and does not apply ?p=page.
Here is the complete function, check the last few lines....
function getSPList( urlObj, options ){
var pageName = urlObj.hash.replace( /.*p=/, "" ),
pageSelector = urlObj.hash.replace( /\?.*$/, "" );
$.ajax({
url:"getSPList.php",
dataType: 'json',
data: {p: pageName},
success:function(result){
if ( result ) {
var $page = $( pageSelector ),
$header = $page.children( ":jqmData(role=header)" ),
$content = $page.children( ":jqmData(role=content)" ),
markup = "<ul data-role='listview' data-filter='true' data-filter-placeholder='Search Salesperson...'>";
for ( var i = 0; i < result.sp.length; i++ ) {
markup += "<li><a href='#addClient?p="+ result.sp[i].id +"' data-transition='slide'>" + result.sp[i].name + "</a></li>";
}
markup += "</ul>";
$content.html( markup );
$page.page();
$content.find( ":jqmData(role=listview)" ).listview();
options.dataUrl = urlObj.href;
options.changeHash = true;
$.mobile.changePage( $page, options );
}
}
});
return
}
I have experienced the same problem and here is what I've found as of version 1.3.2:
Inside $.mobile.changePage(toPage, options) options.dataUrl is passed through path.convertUrlToDataUrl() before being stored and used.
Inside path.convertUrlToDataUrl() everything before and including the '#' as well as everything after and including the '?' is stripped.
Further down inside of $.mobile.changePage() before the url is passed to $.mobile.navigate() I see this:
// rebuilding the hash here since we loose it earlier on
// TODO preserve the originally passed in path
if( !path.isPath( url ) && url.indexOf( "#" ) < 0 ) {
url = "#" + url;
}
So it seems to be a bug in jQm. For my app I'm adding this inside the bottom of the previously mentioned if statement:
var query_index = (settings.dataUrl || '').indexOf('?');
if (query_index > -1) {
url += settings.dataUrl.substring(query_index);
}
This solves the initial problem but I'm unsure about potential negative side effects or if there is a better workaround out there.

ZF2 Redirect out of Controller

Before all, sorry for my poor english.
Good night/day/afternoon (depending of your location)
Sorry if I ask something that could be searched here, and I searched, even found it, but maybe I di not understand.
I need to check authentication in my controllers, so, I implement a master controller and extend all my real controllers to it. In my master controller I check authentication and do it well, but when I try to redirect an unauthenticated user it crashes!
Searching in web, I realized that "init, preDispatch, etc" methods even don't exist more, just the "construct" method, so I try in it, but in construct there is not an event manager, so I stop here...
This is my code:
public function __construct(){
$r = new SimpleRouteStack();
$r->addRoute('logoff', Literal::factory(array(
'route'=>'/suporte/logoff',
'defaults' => array(
'action' => 'logoff',
'controller' => 'Suporte\Controller\Index',
)
)
)
);
$e = new MvcEvent();
$e->setRouter($r);
$this->setEvent($e);
$this->getEvent()->setResponse(new Response());
$this->getEventManager()->attach('*',array($this,'mvcPreDispatch'),100);
public function mvcPreDispatch(){
$uri = explode('/',substr($_SERVER['REQUEST_URI'],1));
$uri[2] = !isset($uri[2]) ? "index" : $uri[2];
$auth = new AuthenticationService();
$identity = $auth->getStorage()->read();
$acl = $identity[2];
if (!$auth->hasIdentity()){
$this->redirect()->toRoute('suporte/logoff');
}elseif ( !$acl->hasResource($uri[0].'/'.$uri[1])
||
!$acl->isAllowed($identity[1],
$uri[0].'/'.$uri[1],
$uri[2]
)
)
$this->redirect()->toRoute('logoff');
else{
/* $this->layout()->id = $identity[0]->getId();
$this->layout()->nome = $identity[0]->getNome();
$this->layout()->cargo = $identity[0]->getCargo(); */
echo "permitido";
//$this->layout()->recursos = $this->acl->getResources();
}
}
is your Suporte\Controller\logoff also extending the masterclass. If yes then it will lead to an infinite loop indexController>masterController(!loggedin)>logoutController>masterController(!loggedin)>logoutController>..
How I used to say "IT is witchcraft"!!!
When I wake up today, turn on my computer, test the controller and BAZINGA!!! is running ok...
Why? I don't dare to question...
my code is that:
abstract class PadraoControllerSuporte extends AbstractActionController{
public function setEventManager(EventManagerInterface $events){
parent::setEventManager($events);
$controller = $this;
$events->attach('dispatch', function ($e) use ($controller) {
if (is_callable(array($controller, 'verificaAuth'))){
call_user_func(array($controller, 'verificaAuth'));
}
}, 100);
}
public function verificaAuth(){
$uri = explode('/',substr($_SERVER['REQUEST_URI'],1));
$uri[2] = !isset($uri[2]) ? "index" : $uri[2];
$auth = new AuthenticationService();
$identity = $auth->getStorage()->read();
$acl = $identity[2];
if (!$auth->hasIdentity())
$this->redirect()->toRoute('suporte/logoff');
elseif ( !$acl->hasResource($uri[0].'/'.$uri[1]) !$acl->isAllowed( $identity[1],
$uri[0].'/'.$uri[1],
$uri[2]
)
)
$this->redirect()->toRoute('logoff');
else{
/* $this->layout()->id = $identity[0]->getId();
$this->layout()->nome = $identity[0]->getNome();
$this->layout()->cargo = $identity[0]->getCargo(); */
echo "permitido";
//$this->layout()->recursos = $this->acl->getResources();
}
}
What I understood:
I think that "setEventManager" was superimposed, so it sets to listen the "dispatch" event and call my verificaAuth function what redirects (if not authenticated) to logoff or allow it is authenticated.
Hope this is usefull...
Thanks for all!!!

nicUpload says "Invalid Upload ID", cant make it works

Im trying to implement nicEdit with the nicupload plugin, but when I select a file to upload it says "Failed to upload image", and the server response says "Invalid Upload ID".
This is the code that calls the script and initializes:
<script src="http://js.nicedit.com/nicEdit-latest.js" type="text/javascript"></script>
<script type="text/javascript">//<![CDATA[
bkLib.onDomLoaded(function() {
new nicEditor({uploadURI : '../../nicedit/nicUpload.php'}).panelInstance('area1');
});
//]]>
</script>
The path to nicUpload.php is correct, and the code is the one that can be found in the documentation: http://nicedit.com/src/nicUpload/nicUpload.js
I made the upload folder changes, and set write permissions. According to the documentation (http://wiki.nicedit.com/w/page/515/Configuration%20Options), thats all, but i keep getting errors. Any ideas?
After looking for an solution a long time (lot of posts without real solution), i now fixed the code myself. I'm now able to upload an image to my own server. Thx to firebug and eclipse ;-)
The main problem is that the nicUpload.php is old and not working with the current nicEdit-Upload function.
Missing is the error handling, feel free to add this...
Add the nicEditor to your php file and configure it to use the nicEdit.php:
new nicEditor({iconsPath : 'pics/nicEditorIcons.gif', uploadURI : 'script/nicUpload.php'}
Download the nicEdit.js uncompressed and change the following lines in nicEdit.js:
uploadFile : function() {
var file = this.fileInput.files[0];
if (!file || !file.type.match(/image.*/)) {
this.onError("Only image files can be uploaded");
return;
}
this.fileInput.setStyle({ display: 'none' });
this.setProgress(0);
var fd = new FormData();
fd.append("image", file);
fd.append("key", "b7ea18a4ecbda8e92203fa4968d10660");
var xhr = new XMLHttpRequest();
xhr.open("POST", this.ne.options.uploadURI || this.nicURI);
xhr.onload = function() {
try {
var res = JSON.parse(xhr.responseText);
} catch(e) {
return this.onError();
}
//this.onUploaded(res.upload); // CHANGE HERE
this.onUploaded(res);
}.closure(this);
xhr.onerror = this.onError.closure(this);
xhr.upload.onprogress = function(e) {
this.setProgress(e.loaded / e.total);
}.closure(this);
xhr.send(fd);
},
onUploaded : function(options) {
this.removePane();
//var src = options.links.original; // CHANGE HERE
var src = options['url'];
if(!this.im) {
this.ne.selectedInstance.restoreRng();
//var tmp = 'javascript:nicImTemp();';
this.ne.nicCommand("insertImage", src);
this.im = this.findElm('IMG','src', src);
}
var w = parseInt(this.ne.selectedInstance.elm.getStyle('width'));
if(this.im) {
this.im.setAttributes({
src : src,
width : (w && options.image.width) ? Math.min(w, options.image.width) : ''
});
}
}
Change the nicUpload.php like this
<?php
/* NicEdit - Micro Inline WYSIWYG
* Copyright 2007-2009 Brian Kirchoff
*
* NicEdit is distributed under the terms of the MIT license
* For more information visit http://nicedit.com/
* Do not remove this copyright message
*
* nicUpload Reciever Script PHP Edition
* #description: Save images uploaded for a users computer to a directory, and
* return the URL of the image to the client for use in nicEdit
* #author: Brian Kirchoff <briankircho#gmail.com>
* #sponsored by: DotConcepts (http://www.dotconcepts.net)
* #version: 0.9.0
*/
/*
* #author: Christoph Pahre
* #version: 0.1
* #description: different modification, so that this php file is working with the newest nicEdit.js (needs also modification - #see)
* #see http://stackoverflow.com/questions/11677128/nicupload-says-invalid-upload-id-cant-make-it-works
*/
define('NICUPLOAD_PATH', '../images/uploadedImages'); // Set the path (relative or absolute) to
// the directory to save image files
define('NICUPLOAD_URI', '../images/uploadedImages'); // Set the URL (relative or absolute) to
// the directory defined above
$nicupload_allowed_extensions = array('jpg','jpeg','png','gif','bmp');
if(!function_exists('json_encode')) {
die('{"error" : "Image upload host does not have the required dependicies (json_encode/decode)"}');
}
if($_SERVER['REQUEST_METHOD']=='POST') { // Upload is complete
$file = $_FILES['image'];
$image = $file['tmp_name'];
$id = $file['name'];
$max_upload_size = ini_max_upload_size();
if(!$file) {
nicupload_error('Must be less than '.bytes_to_readable($max_upload_size));
}
$ext = strtolower(substr(strrchr($file['name'], '.'), 1));
#$size = getimagesize($image);
if(!$size || !in_array($ext, $nicupload_allowed_extensions)) {
nicupload_error('Invalid image file, must be a valid image less than '.bytes_to_readable($max_upload_size));
}
$filename = $id;
$path = NICUPLOAD_PATH.'/'.$filename;
if(!move_uploaded_file($image, $path)) {
nicupload_error('Server error, failed to move file');
}
$status = array();
$status['done'] = 1;
$status['width'] = $size[0];
$rp = realpath($path);
$status['url'] = NICUPLOAD_URI ."/".$id;
nicupload_output($status, false);
exit;
}
// UTILITY FUNCTIONS
function nicupload_error($msg) {
echo nicupload_output(array('error' => $msg));
}
function nicupload_output($status, $showLoadingMsg = false) {
$script = json_encode($status);
$script = str_replace("\\/", '/', $script);
echo $script;
exit;
}
function ini_max_upload_size() {
$post_size = ini_get('post_max_size');
$upload_size = ini_get('upload_max_filesize');
if(!$post_size) $post_size = '8M';
if(!$upload_size) $upload_size = '2M';
return min( ini_bytes_from_string($post_size), ini_bytes_from_string($upload_size) );
}
function ini_bytes_from_string($val) {
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
function bytes_to_readable( $bytes ) {
if ($bytes<=0)
return '0 Byte';
$convention=1000; //[1000->10^x|1024->2^x]
$s=array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB');
$e=floor(log($bytes,$convention));
return round($bytes/pow($convention,$e),2).' '.$s[$e];
}
?>
You can manually pass an id to your script: e.g nicUpload.php?id=introPicHeader and it will become introPicHeader.jpg (or appropriate extension) in the images folder you defined.
However, I have noticed that this script is broken and cannot access the configuration option uploadURI if specified directly in nicEdit.js during the nicEditorAdvancedButton.extend({. This causes access to an relatively pathed "Unknown" resource, causing an error.
The documentation implies otherwise and the fact that the nicURI was specified here for imgur.com (maybe as a default) gave me the impression I could also add a uploadURI reference to the nicUpload.php script in a single place rather than on every editor instantiation.
Update
This works if you pass it during instantiation, which I guess does allow for easy dynamic id population.
Unfortunately, the nicUpload.php is riddled with errors and it's output is not JSON. The editor expects to parse JSON and finds a script tag and errors with unexpected token "<".
There are a raft of other errors which I will attempt to identify:
In nicEdit.js
A.append("image") should be infact A.append("nicImage")
this.onUploaded(D.upload) should become this.onUploaded(D)
this.onUploaded(D) should be moved to within the try block after var D=JSON.parse(C.responseText) to fix variable scope issues
B.image.width needs to become B.width
In nicUpload.php
JSON output is not formed correctly, comment out html output and output just json_encode($status).
JSON output needs to return a key/value pair named links rather than url although renaming the var D=B.links to var D=B.url in nicEdit.js would also suffice as a fix.
Both php and javascript code leaves a lot to be desired, I get many errors regularly and have been fixing them myself.

jqueryui autocomplete: lists entries with search terms in middle

I am using jqueryui autocomplete widget for autocompleting a 'country' field but I am facing an issue. Suppose the user enters "in", I want the jqueryui to list countries like 'india', 'indonesia' which start with 'in', but it also lists the countries which have 'in' somewhere in the name (like: argentina). How can I solve this issue?
jQuery(".autocomplete").autocomplete({
source: CountrySuggestions, //CountrySuggestions is an array in javascript containing the list of countries
minLength: 2
});
Akshey
Unfortunately, it appears as though the jQueryUI Autocomplete was made to not allow this on an array source. You can, however, hook the plugin's _initSource function to force a "starts with" regular expression token ( ^ ) on the search as below.
I think this was probably overlooked because the majority of its usage was thought to be in the remote retrieval. Either way, not a pretty fix, but due to the regex stripping function, it's the only solution that came to mind.
$.ui.autocomplete.prototype._initSource = function() {
var array,
url;
if ( $.isArray(this.options.source) ) {
array = this.options.source;
this.source = function( request, response ) {
// escape regex characters
var matcher = new RegExp( "^"+$.ui.autocomplete.escapeRegex(request.term), "i" );
response( $.grep( array, function(value) {
return matcher.test( value.label || value.value || value );
}) );
};
} else if ( typeof this.options.source === "string" ) {
url = this.options.source;
this.source = function( request, response ) {
$.getJSON( url, request, response );
};
} else {
this.source = this.options.source;
}
};
$("#countries").autocomplete({
source: ["India","Indonesia","Argentina"],
minLength: 2
});

Resources