Cant understand what's happening - php

i'm trying Zend framework, i've got two folders in E:\Archivos de programa\Zend\ZendServer\share, une is ZendServer and the other one is ZendServer2
I can't recall if i ever install this two version but i dont think this is the problem
I'm using netbeans as ide ando i'm trying to make an ABM of users using BlockCipher
Here is my code
<?php
use Zend\Crypt\BlockCipher;
class Application_Model_DbTable_Usuarios extends Zend_Db_Table_Abstract
{
protected $_name = 'usuario';
public function getUsuario($usuario)
{
$usuario = (string)$usuario;
$row = $this->fetchRow('Usuario = ' . $usuario);
if (!$row) {
throw new Exception("Could not find row $usuario");
}
return $row->toArray();
}
public function addUsuario($usuario, $clave)
{
$blockCipher = Zend\Crypt\BlockCipher::factory('mcrypt',array('algo'=>'aes'));
$blockCipher->setKey('encryption key');
$result = $blockCipher->encrypt($clave);
echo "Encrypted text: $result \n";
exit;
$data = array(
'Usuario' => $usuario,
'Clave' => $blockCipher,
);
$this->insert($data);
}
public function updateUsuario($usuario, $clave)
{
$blockCipher = BlockCipher::factory($clave, array(
'algo' => 'blowfish',
'mode' => 'cfb',
'hash' => 'sha512'
));
$data = array(
'Clave' => $blockCipher,
);
$this->update($data, 'Usuario = ' . (string)$usuario);
}
public function deleteUsuario($usuario)
{
$this->delete('Usuario = ' . (string)$usuario);
}
}
and in my php.ini i've got
include_path=".;E:\Archivos de programa\Zend\ZendServer\share\ZendFramework2\library"
And i get this error
Fatal error: Class 'Zend\Crypt\BlockCipher' not found in E:\Documents and Settings\dvieira\Mis documentos\NetBeansProjects\justforgeeks\application\models\DbTable\Usuarios.php on line 21
I dont understand why.
Can you help me please?
Thanks in advance

You are using namespaces in your application, therefore you need to make sure that your autoloader can handle this. If it's a ZF1 app then not. Can you try using require to include the class file instead? You can ass well amend the autoloader to work with namespaces
Secondly when using namespaces, if you create an alias for a class
use Zend\Crypt\BlockCipher;
you then instantiate it
$blockCipher = BlockCipher::factory('mcrypt',array('algo'=>'aes'));

Related

Sending datas to multiple tables - CakePHP 3.2

I'm trying to do a chat system, I'm having troubles with it, my ideia is the following:
When the user send a message, this message has to be saved in 2 tables in my database... But it isn't working, the message is saving in only one table.
public function sendMessage()
$data = $this->request->data();
$sessionId = $data['idSession'];
$userId = $this->request->session()->read('Auth.User.id');
$msg = $data['message'];
$typeMessage = $data['type'];
$messageTable = TableRegistry::get('messages');
$messageAllTable = TableRegistry::get('mensage_alls');
if ($typeMessage == 1)
{
$message['session_private_id'] = $sessionId;
}
else
{
$message['session_id'] = $sessionId;
}
$message = array_merge($message, array(
'user_id' => $userId,
'message' => $msg,
'created_at' => new \DateTime(date("Y-m-d H:i:s")),
));
$messageEntity = $messageTable->newEntity();
$messageEntity = $messageTable->patchEntity($messageEntity, $message, ['validate' => false]);
$resposta = $messageTable->save($messageEntity);
$this->response->body($resposta);
return $this->response;
I'm a beginner in CakePHP, so, don't need to call me a dumb.
Thanks since now. And sorry for my bad english.
Ignoring the reason why you'd want to duplicate the data (it doesn't sound like a good thing generally speaking), the reason it doesn't work is you never saved it to the 2nd table. You need to call something at minimum like:
$resposta = $messageTable->save($messageEntity);
$messageCopy = $messageAllTable->newEntity($messageEntity);
$respostaCopy = $messageAllTable->save($messageCopy);
$this->response->body($resposta && $respostaCopy);
If you meant you want to to always automatically copy to a secondary table, then you could instead add a Behavior to the main Message Table. For example, a bare-bones version would look like:
In MessageTable.php:
namespace App\Model\Table;
use Cake\ORM\Table;
class MessageTable extends Table
{
public function initialize(array $config)
{
// Add this line
$this->addBehavior('CopyMessage');
}
}
And create a src/Model/Behavior/CopyMessageBehavior.php:
namespace App\Model\Behavior;
use Cake\ORM\Behavior;
class CopyMessageBehavior extends Behavior
{
public function copyMessage(Entity $entity)
{
$messageAllTable = TableRegistry::get('mensage_alls');
$messageCopy =messageAllTable->newEntity($messageEntity);
$messageAllTable->save($messageCopy);
}
public function beforeSave(Event $event, EntityInterface $entity)
{
$this->copyMessage($entity);
}
}

Variable of object set in construct is out of scope in destruct

So, I started writing a bootstrap script for a micro framework I'm working on for learning purposes (both learn more about programming, php and oop) and I came across this weird unexpected behavior.
The variable $config which starts a new object of Config() class is being called in Bootstrap's __construct which is public, then it is being used in Bootstrap's __destruct which is also public. The variable itself of $config is public and declared before __construct as you can see below.
Now, what's weird is that I get a notice and fatal error from using $config in __destruct, it says the variable doesn't exist and the fatal error is calling a member function on a non object (because $config doesn't exist)
Here is the script, hope someone could point out why this weird behavior happens, it is possible that I'm missing something and the behavior makes sense but well, I'm missing it then please point it out.
<?php
basename($_SERVER["PHP_SELF"]) == "bootstrap.php" ? die("No direct script access allowed") : '';
class Bootstrap
{
public $config;
protected $start_route;
public function __construct()
{
$this->settings();
$config = new Config();
$this->database();
$this->routing();
$start_route = new Route($config);
$start_route->initiate();
}
public function run()
{
$db_info = new DatabaseInfo();
$database = new Database([
'database_type' => $db_info->get_db('dbdriver'),
'database_name' => $db_info->get_db('database'),
'server' => $db_info->get_db('hostname'),
'username' => $db_info->get_db('username'),
'password' => $db_info->get_db('password'),
'charset' => $db_info->get_db('dbcharset'),
'port' => $db_info->get_db('port'),
'prefix' => $db_info->get_db('dbprefix'),
// driver_option for connection, read more from
// http://www.php.net/manual/en/pdo.setattribute.php
'option' => [
PDO::ATTR_CASE => PDO::CASE_NATURAL
]
]);
/*
*
* Read is much faster than Write,
* while INSERT will increase load time by ~40ms per each query,
* COUNT will only increase by ~2ms
*
*/
$count = $database->count('site_log', [
'log_type' => 1
]);
/*
$database->insert('site_log', [
'remote_addr' => '127.0.0.1',
'request_uri' => '/',
'log_type' => 1,
'message' => 'Test Query'
]);
*/
echo 'The are ' . $count . ' rows in log with severity level of 1!<br />';
}
// Since it's being called from __constrcut, it will run before run()
private function settings()
{
require BOOTPATH.'core\\config'.CLASSFIX.EXT;
}
// Since it's being called from __constrcut, it will run before run()
private function database()
{
require BOOTPATH.'core\\database'.CLASSFIX.EXT;
return;
}
// Since it's being called from __constrcut, it will run before run()
private function routing()
{
require BOOTPATH.'core\\router'.CLASSFIX.EXT;
return;
}
// Since it's being outputed within __destrcut, it will run after run() and basically last
public function __destruct()
{
$script_end = (float) array_sum( explode( ' ',microtime() ) );
echo 'Welcome to ' . $config->get_conf('site_name') . '<br />';
echo 'Processing time: '. sprintf( '%.4f', ( $script_end - APP_START ) ).' seconds';
}
}
When you do this:
$config = new Config();
you are creating a new $config object in the scope of the constructor, you are not populating the $config property of the Bootstrap class
You have to use $this->config; to access the class property

Parsing RSS file with zend 2 feed , i cant get media tag

I just can't seem to be able to solve this. I want to get the media:thumbnail from an RSS file . using ZF2 ; Zend\Frame a follow the manual but i cant get images from the xml file , any idea plz :)
that the controller Code :
<?php
namespace RSS\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Feed\Reader as feed;
class IndexController extends AbstractActionController
{
public function indexAction(){
try{
$rss = feed\Reader::import('http://www.wdcdn.net/rss/presentation/library/client/skunkus/id/cc3d06c1cc3834464aef22836c55d13a');
}catch (feed\Exception\RuntimeException $e){
echo "error : " . $e->getMessage();
exit;
}
$channel = array(
'title' => $rss->getTitle(),
'description' => $rss->getDescription(),
'link' => $rss->getLink(),
'items' => array()
);
foreach($rss as $item){
$channel['items'][] = array(
'title' => $item->getTitle(),
'link' => $item->getLink(),
'description' => $item->getDescription(),
// 'image' => $item->getImage(),
);
}
return new ViewModel(array(
'channel' => $channel
));
}
}
Hi
for who get the same pb i solve it by adding a new function to Zend/Feed/Reader/Entry/rss.php called getMedia() , that the code for who has a better idea or a better code i'll be thankful if you help :
public function getMedia()
{
if (array_key_exists('media', $this->data)) {
return $this->data['media'];
}
$media = null;
if ($this->getType() == Reader\Reader::TYPE_RSS_20) {
$nodeList = $this->xpath->query($this->xpathQueryRss . '/media:thumbnail');
if ($nodeList->length > 0) {
$media = new \stdClass();
$media->url = $nodeList->item(0)->getAttribute('url');
}
}
$this->data['media'] = $media;
return $this->data['media'];
}
Here is a way to do it without having to extend or modify the class:
foreach ($channel as $item) {
$xmlItem = $item->saveXml();
$xmlFeed = new \SimpleXMLElement($xmlItem);
$thumbAttr = $xmlFeed->children('http://search.yahoo.com/mrss/')->thumbnail->attributes();
$thumbUrl = (string)$thumbAttr['url'];
}

How to implement custom ACLs for CalDAV in SabreDAV PHP Server

So far I have been unable to successfully implement ACLs (permissions) in SabreDAV.
I have implemented SabreDAV in Code Igniter with my own Auth, Principal and CalDAV backend. This the actual code from the controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class CalDAV extends CI_Controller {
public function _remap() {
$this->load->library('SabreDAV');
$authBackend = new SabreDAV_DAV_Auth_Backend_Tank_Auth;
$principalBackend = new Sabre_DAVACL_PrincipalBackend_Click4Time;
$calendarBackend = new Sabre_CalDAV_Backend_Click4Time;
// Directory tree
$tree = array(
new Sabre_DAVACL_PrincipalCollection($principalBackend),
new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend)
);
// The object tree needs in turn to be passed to the server class
$server = new Sabre_DAV_Server($tree);
// You are highly encouraged to set your WebDAV server base url. Without it,
// SabreDAV will guess, but the guess is not always correct. Putting the
// server on the root of the domain will improve compatibility.
$server->setBaseUri('/caldav/');
// Authentication plugin
$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend, 'SabreDAV');
$server->addPlugin($authPlugin);
// CalDAV plugin
$caldavPlugin = new Sabre_CalDAV_Plugin();
$server->addPlugin($caldavPlugin);
// ACL plugin
$aclPlugin = new Sabre_DAVACL_Custom;
$server->addPlugin($aclPlugin);
// Support for html frontend
$browser = new Sabre_DAV_Browser_Plugin();
$server->addPlugin($browser);
$server->exec();
}
}
My current attempt at implementing permissions has been through my custom ACL Plugin:
<?php
class Sabre_DAVACL_Custom extends Sabre_DAVACL_Plugin {
public $allowAccessToNodesWithoutACL = false;
private function _getCurrentUserName() {
$authPlugin = $this->server->getPlugin('auth');
if (is_null($authPlugin)) return null;
return $authPlugin->getCurrentUser();
}
public function getACL($node) {
$user = $this->_getCurrentUserName();
$path = $node->getName();
if ($path == 'calendars' || $path == 'principals' || $path == 'root') {
return array(
array(
'privilege' => '{DAV:}read',
'principal' => 'principals/' . $user,
'protected' => true,
)
);
}
else if ($path == 'calendars/' . $user) {
return array(
array(
'privilege' => '{DAV:}read',
'principal' => 'principals/' . $user,
'protected' => true,
)
);
}
return array();
}
}
This code pretty much works except the second check which should authorize the user to see his or her own calendar(s). I am unable to get the full path name for $node.
This may be the wrong way to implement but I have been unable to find any documentation to confirm that this is the way to implement ACLs.
i'm using a different attempt, i extended the plugin, just like you did but then i replaced getSupportedPrivilegeSet($node) instead.
in sabredav 1.8.6 it looks like this:
public function getSupportedPrivilegeSet($node) {
if (is_string($node)) {
$node = $this->server->tree->getNodeForPath($node);
}
if ($node instanceof IACL) {
$result = $node->getSupportedPrivilegeSet();
if ($result)
return $result;
}
return self::getDefaultSupportedPrivilegeSet();
}
now you can use the classes instead of the path which i found more usefull, i.e.:
class DavCalAcl extends \Sabre\DAVACL\Plugin {
public function getSupportedPrivilegeSet($node) {
if (is_string($node)) {
$node = $this->server->tree->getNodeForPath($node);
}
if($node instanceof \Sabre\CalDAV\Calendar || $node instanceof \Sabre\CalDAV\CalendarObject) {
return array(
array(
'privilege' => '{DAV:}read',
'aggregates' => array(
array(
'privilege' => '{DAV:}read-acl',
'abstract' => true,
),
array(
'privilege' => '{DAV:}read-current-user-privilege-set',
'abstract' => true,
),
),
)
);
}
if ($node instanceof \Sabre\DAVACL\IACL) {
$result = $node->getSupportedPrivilegeSet();
if ($result)
return $result;
}
return self::getDefaultSupportedPrivilegeSet();
}
}
this is my current attempt to get iCal to recognize a calendar as read-only... i'm not quite there yet but maybe this will help you in better identifying the objects
if you want the absolute path of a node i guess you could always go to the root search it for your current node and by doing so recording the path which took you there. as far as i checked the nodes in sabredav do not support a parent or a root property.
[UPDATE]
the best way seems to be to override getACL in the plugin. here you can test for the node's class and return what you really want on instead of the stuff which is returned by the default objects (for instance look at UserCalendars->getACL().
here's my working solution for read-only enforcement based on the object types:
class DavCalAcl extends \Sabre\DAVACL\Plugin {
/**
* Returns the full ACL list.
*
* Either a uri or a DAV\INode may be passed.
*
* null will be returned if the node doesn't support ACLs.
*
* #param string|DAV\INode $node
* #return array
*/
public function getACL($node) {
if (is_string($node)) {
$node = $this->server->tree->getNodeForPath($node);
}
if (!$node instanceof \Sabre\DAVACL\IACL) {
return null;
}
if( $node instanceof \Sabre\CalDAV\Calendar ||
$node instanceof \Sabre\CalDAV\CalendarObject ||
$node instanceof \Sabre\CalDAV\UserCalendars
) {
$acl = array(
array(
'privilege' => '{DAV:}read',
'principal' => $node->getOwner(),
'protected' => true,
),
);
} else {
$acl = $node->getACL();
}
foreach($this->adminPrincipals as $adminPrincipal) {
$acl[] = array(
'principal' => $adminPrincipal,
'privilege' => '{DAV:}all',
'protected' => true,
);
}
return $acl;
}
}

How do you handle errors when using a service layer?

in my Zend Framework project, I use a Service Layer, however I don't really know where to handle errors.
For example, let's say I've a UserService::updateUser($data);
What if I've:
$data = array(
'userId' => 2,
'firstName' => 'Jane',
'lastName' => 'Doe',
);
And user with id 2 doesn't exist?
Where and how would you handle such errors?
You can forward to a specific controller to handle all your business errors, like this :
if ($error=true)
return $this->_forward('standarderror', 'businesserror', 'default',
array('msgtitle' => $this->view->translate('item_not_found'),
'msg' => $this->view->translate('item_not_found_msg')));
and where your BusinesserrorController looks like :
class BusinesserrorController extends Zend_Controller_Action {
public function init() {
$this->_helper->viewRenderer->setNoRender();
}
public function standarderrorAction() {
$msgtitle = $this->_getParam('msgtitle');
$msg = $this->_getParam('msg');
$this->view->errortitle = $msgtitle;
$this->view->errormessage = $msg;
$this->view->nextstep = $this->view->translate('return_to_the_homepage');
$this->view->nextstepurl = "/";
echo $this->render('error/businesserror', null, true);
}
}
you can parametrize the forwarded url as well ;)

Categories