├── README.md ├── ShoppingCart.php └── composer.json /README.md: -------------------------------------------------------------------------------- 1 |
Phalcon cart provides complet cart system, allows you to create multiple instances to have all the areas we want independently.
3 |4 | If ocurred any problem with proccess cart, the class store logs into app/logs/shoppingCart.log for more info.
5 |6 | Cart works with Phalcon sessions, if you would, you can use adapter sessions for manage cart with database, more info. 7 |
8 | 9 | * [Incubator Link](https://github.com/phalcon/incubator/blob/master/README.md#installing-via-github) 10 | * [Phalcon Sesion Adapter](https://github.com/phalcon/incubator/tree/master/Library/Phalcon/Session/Adapter#phalconsessionadapter) 11 | * [Show demo](http://phalcon-tuts.com/phalconShop) 12 | 13 |Create a new file composer.json, open and add the next code
15 | ```json 16 | { 17 | "require": { 18 | "unodepiera/phalcon_cart": "dev-master" 19 | }, 20 | "minimum-stability": "dev" 21 | } 22 | ``` 23 |Update your packages with composer update or install with composer install.
24 |Now open app/config/loader.php and replace the code.
25 | ```php 26 | 27 | $loader = new \Phalcon\Loader(); 28 | 29 | /** 30 | * We're a registering a set of directories taken from the configuration file 31 | */ 32 | $loader->registerDirs( 33 | array( 34 | $config->application->controllersDir, 35 | $config->application->modelsDir, 36 | $config->application->libraryDir 37 | ) 38 | ); 39 | 40 | //register the new class ShoppingCart 41 | $loader->registerClasses( 42 | array( 43 | "ShoppingCart" => "../vendor/unodepiera/phalcon_cart/ShoppingCart.php", 44 | ) 45 | ); 46 | 47 | $loader->register(); 48 | ``` 49 | 50 |52 | Download file ShoppingCart.php and create a new directory library in app dir. 53 | Save file into library dir and open app/config/loader.php, now update this file. 54 |
55 | ```php 56 | $loader = new \Phalcon\Loader(); 57 | 58 | /** 59 | * We're a registering a set of directories taken from the configuration file 60 | */ 61 | $loader->registerDirs( 62 | array( 63 | $config->application->controllersDir, 64 | $config->application->modelsDir, 65 | $config->application->libraryDir//register dir library dir 66 | ) 67 | ); 68 | 69 | $loader->register(); 70 | ``` 71 |"; 89 | var_dump($this->cart->getContent()); 90 | } 91 | ``` 92 |Insert multiple products
93 | ```php 94 | $products = array( 95 | array( 96 | "id" => 1, 97 | "name" => "Almendras", 98 | "price" => 2.5, 99 | "qty" => 8, 100 | "description" => "Almendras saladas" 101 | ), 102 | array( 103 | "id" => 2, 104 | "name" => "Galletas pou", 105 | "price" => 2.7, 106 | "qty" => 5, 107 | "description" => "Galletas del amigo pou" 108 | ), 109 | array( 110 | "id" => 3, 111 | "name" => "Pasta de dientes", 112 | "price" => 1.80, 113 | "qty" => 8, 114 | "description" => "Pasta de dientes......" 115 | ) 116 | ); 117 | 118 | if($this->cart->addMulti($products) != false) 119 | { 120 | echo ""; 121 | var_dump($this->cart->getContent()); 122 | } 123 | ``` 124 |Update one product
125 | ```php 126 | $product = array( 127 | "id" => 3, 128 | "name" => "Pasta de dientes", 129 | "price" => 1.80, 130 | "qty" => 12, 131 | "description" => "Pasta de dientes......" 132 | ); 133 | 134 | if($this->cart->update($product) != false) 135 | { 136 | echo ""; 137 | var_dump($this->cart->getContent()); 138 | } 139 | ``` 140 |Update multiple products
141 | ```php 142 | $products = array( 143 | array( 144 | "id" => 1, 145 | "name" => "Almendras", 146 | "price" => 2.5, 147 | "qty" => 1, 148 | "description" => "Almendras saladas" 149 | ), 150 | array( 151 | "id" => 2, 152 | "name" => "Galletas pou", 153 | "price" => 2.7, 154 | "qty" => 1, 155 | "description" => "Galletas del amigo pou" 156 | ), 157 | array( 158 | "id" => 3, 159 | "name" => "Pasta de dientes", 160 | "price" => 1.80, 161 | "qty" => 1, 162 | "description" => "Pasta de dientes......" 163 | ) 164 | ); 165 | 166 | if($this->cart->updateMulti($products) != false) 167 | { 168 | echo ""; 169 | var_dump($this->cart->getContent()); 170 | } 171 | ``` 172 |Check and print options
173 |Check if product has options and print, need his rowId
174 | ```php 175 | if($this->cart->hasOptions("0e043c0cd48de80fa4f6ed23a15d6d10") != false) 176 | { 177 | echo ""; 178 | var_dump($this->cart->getOptions("0e043c0cd48de80fa4f6ed23a15d6d10")); 179 | } 180 | ``` 181 |Get total price cart
182 | ```php 183 | echo $this->cart->getTotal(); 184 | ``` 185 |Get total items cart
186 | ```php 187 | echo $this->cart->getTotalItems(); 188 | ``` 189 |Remove a product
190 |You just need to pass a rowid that there
191 | ```php 192 | if($this->cart->removeProduct("0e043c0cd48de80fa4f6ed23a15d6d10") != false) 193 | { 194 | echo ""; 195 | var_dump($this->cart->getContent()); 196 | } 197 | ``` 198 |Remove a cart
199 |You just need that there
200 | ```php 201 | if($this->cart->destroy() != false) 202 | { 203 | echo ""; 204 | var_dump($this->cart->getContent()); 205 | } 206 | ``` 207 |Get cart content
208 | ```php 209 | var_dump($this->cart->getContent()); 210 | ``` 211 | 212 | ## Visit me 213 | 214 | * [Visit me](http://uno-de-piera.com) 215 | * [Phalcon Cart on Packagist](https://packagist.org/packages/unodepiera/phalcon_cart) 216 | * [License](http://www.opensource.org/licenses/mit-license.php) 217 | -------------------------------------------------------------------------------- /ShoppingCart.php: -------------------------------------------------------------------------------- 1 | _identificator = $cartIdentificator; 43 | 44 | //set cart session 45 | if($this->session->has($this->_identificator) !== FALSE) 46 | { 47 | $this->_cart = $this->session->get($this->_identificator); 48 | } 49 | } 50 | 51 | /** 52 | * @desc - create a new instance for log class 53 | * @access private 54 | * @author Iparra 55 | */ 56 | private function _instanceLog() 57 | { 58 | $this->_createLogDir(); 59 | $this->_logger = new FileAdapter("../app/logs/shoppingCart.log"); 60 | } 61 | 62 | /** 63 | * @desc - set session cart and save content cart into session 64 | * @access private 65 | * @author Iparra 66 | */ 67 | private function _save() 68 | { 69 | $this->session->set($this->_identificator, $this->_cart); 70 | } 71 | 72 | /** 73 | * @desc - add product to cart 74 | * @access public 75 | * @author Iparra 76 | * @param $product - array with product data to add 77 | */ 78 | public function add($product = array(), $isUpdate = FALSE) 79 | { 80 | //check if is array and not empty, otherwise write log message and return false 81 | if(!is_array($product) || empty($product)) 82 | { 83 | $this->_logNotArray(__LINE__); 84 | return false; 85 | } 86 | 87 | //check if isset keys id qty and price, otherwise return false 88 | if(!$product["id"] || !$product["qty"] || !$product["price"]) 89 | { 90 | $this->_instanceLog(); 91 | $this->_logger->error( 92 | "Error, the product need next keys: id, qty and price, line ".__LINE__." class ".__CLASS__."!" 93 | ); 94 | return false; 95 | } 96 | 97 | //check if is numeric values id qty and price, otherwise return false 98 | if(!is_numeric($product["id"]) || !is_numeric($product["qty"]) || !is_numeric($product["price"])) 99 | { 100 | $this->_instanceLog(); 101 | $this->_logger->error( 102 | "Error, the product should have numerics id, qty y price, line ".__LINE__." class ".__CLASS__."!" 103 | ); 104 | return false; 105 | } 106 | 107 | //we must create a rowId identifier for each product 108 | if(isset($product['options'])) 109 | { 110 | $rowId = md5($product['id'].serialize($product['options'])); 111 | } 112 | else 113 | { 114 | $rowId = md5($product["id"]); 115 | } 116 | 117 | //create the rowId id for the product 118 | $product["rowId"] = $rowId; 119 | 120 | //if not empty cart we loop 121 | if(!empty($this->_cart)) 122 | { 123 | foreach ($this->_cart as $row) 124 | { 125 | //check if this product was already in the 126 | //cart for add or update a product 127 | if($row["rowId"] === $rowId && $isUpdate === FALSE) 128 | { 129 | //if isset only add refresh qty items 130 | $product["qty"] = $row["qty"] + $product["qty"]; 131 | } 132 | } 133 | } 134 | 135 | //qty and price may only be positive numbers 136 | $product["qty"] = trim(preg_replace('/([^0-9\.])/i', '', $product["qty"])); 137 | $product["price"] = trim($this->_formatNumber($product["price"])); 138 | 139 | //add to cart total price of the sum of this article 140 | $product["total"] = $this->_formatNumber($product["qty"] * $product["price"]); 141 | 142 | //must first remove the product if it was in the cart 143 | $this->removeProduct($rowId); 144 | 145 | ///add the product to cart 146 | $this->_cart[$rowId] = $product; 147 | 148 | //update the total price and the number of items in shopping cart 149 | $this->_updatePriceQty(); 150 | 151 | return true; 152 | } 153 | 154 | /** 155 | * @desc - add multiple products to cart 156 | * @access public 157 | * @author Iparra 158 | * @param $products - array with product data to add 159 | */ 160 | public function addMulti($products = array()) 161 | { 162 | //check if is array and not empty, otherwise return false 163 | if(!is_array($products) || empty($products)) 164 | { 165 | $this->_logNotArray(__LINE__); 166 | return false; 167 | } 168 | 169 | foreach($products as $product) 170 | { 171 | $this->add($product); 172 | } 173 | return true; 174 | } 175 | 176 | /** 177 | * @desc - update info product 178 | * @access public 179 | * @author Iparra 180 | * @param $product - array with product data to update 181 | */ 182 | public function update($product = array()) 183 | { 184 | //check if is array and not empty, otherwise return false 185 | if(!is_array($product) || empty($product)) 186 | { 187 | $this->_logNotArray(__LINE__); 188 | return false; 189 | } 190 | //update product with method add and second param to true 191 | if($this->add($product, TRUE) === true) 192 | { 193 | return true; 194 | } 195 | } 196 | 197 | /** 198 | * @desc - update multiple products 199 | * @access public 200 | * @author Iparra 201 | * @param $products - array with products data to update 202 | */ 203 | public function updateMulti($products = array()) 204 | { 205 | //check if is array and not empty, otherwise return false 206 | if(!is_array($products) || empty($products)) 207 | { 208 | $this->_logNotArray(__LINE__); 209 | } 210 | //update each product with method add and second param to true 211 | foreach($products as $product) 212 | { 213 | $this->add($product, TRUE); 214 | } 215 | return true; 216 | } 217 | 218 | /** 219 | * @desc - write to log error message if data product is incorrect 220 | * @access private 221 | * @author Iparra 222 | */ 223 | private function _logNotArray($line) 224 | { 225 | $this->_instanceLog(); 226 | $this->_logger->error( 227 | "Error, the product add to cart is empty o not is array, line ".$line." class ".__CLASS__."!" 228 | ); 229 | } 230 | 231 | /** 232 | * @desc - remove a product by rowid and update content cart 233 | * @access private 234 | * @author Iparra 235 | * @return bool 236 | */ 237 | private function _updatePriceQty() 238 | { 239 | //set price and product to 0 240 | $price = 0; 241 | $products = 0; 242 | 243 | //loop cart and update price and qty products 244 | foreach ($this->_cart as $row) 245 | { 246 | $price += $this->_formatNumber(($row['price'] * $row['qty'])); 247 | $products += $row['qty']; 248 | } 249 | 250 | //asign values to total_items and cart_total 251 | $this->_cart["total_items"] = $products; 252 | $this->_cart["cart_total"] = $price; 253 | 254 | //update content cart 255 | $this->_save(); 256 | } 257 | 258 | /** 259 | * @desc - Check if cart item has options 260 | * @access public 261 | * @param $rowid - rowid contains references item would check 262 | * @author Iparra 263 | * @return bool 264 | */ 265 | public function hasOptions($rowId = '') 266 | { 267 | if(!isset($this->_cart[$rowId]['options']) || count($this->_cart[$rowId]['options']) === 0) 268 | { 269 | return FALSE; 270 | } 271 | 272 | return TRUE; 273 | } 274 | 275 | /** 276 | * @desc - get options for product by rowId 277 | * @access public 278 | * @author Iparra 279 | * @param $rowId - rowid contains references item would return 280 | * @return array 281 | */ 282 | public function getOptions($rowId = '') 283 | { 284 | if(!isset($this->_cart[$rowId]['options']) || count($this->_cart[$rowId]['options']) === 0) 285 | { 286 | return array(); 287 | } 288 | 289 | return $this->_cart[$rowId]['options']; 290 | } 291 | 292 | /** 293 | * @desc - return total price in cart 294 | * @access public 295 | * @author Iparra 296 | * @return float 297 | */ 298 | public function getTotal() 299 | { 300 | return $this->_cart['cart_total'] ? $this->_formatNumber($this->_cart['cart_total']) : 0; 301 | } 302 | 303 | // -------------------------------------------------------------------- 304 | 305 | /** 306 | * @desc - return total items in cart 307 | * @access public 308 | * @author Iparra 309 | * @return integer 310 | */ 311 | public function getTotalItems() 312 | { 313 | return $this->_cart['total_items'] ? $this->_cart['total_items'] : 0; 314 | } 315 | 316 | /** 317 | * @desc - format array cart and return content 318 | * @access public 319 | * @author Iparra 320 | * @return array 321 | */ 322 | public function getContent() 323 | { 324 | //asign content cart to $cart var and unset total_items and cart_total 325 | $cart = $this->_cart; 326 | unset($cart["total_items"]); 327 | unset($cart["cart_total"]); 328 | return $cart; 329 | } 330 | 331 | /** 332 | * Format Number 333 | * 334 | * Returns the supplied number with commas and a decimal point. 335 | * 336 | * @access public 337 | * @return integer 338 | */ 339 | private function _formatNumber($number = '') 340 | { 341 | if ($number == '') 342 | { 343 | return ''; 344 | } 345 | 346 | //Remove anything that isn't a number or decimal point 347 | $number = trim(preg_replace('/([^0-9\.])/i', '', $number)); 348 | 349 | return number_format($number, 2, '.', ','); 350 | } 351 | 352 | /** 353 | * @desc - remove a product by rowid and update content cart 354 | * @access public 355 | * @author Iparra 356 | * @param $rowId - product rowid 357 | * @return bool 358 | */ 359 | public function removeProduct($rowId = '') 360 | { 361 | if($this->_removeProduct($rowId) === TRUE) 362 | { 363 | return TRUE; 364 | } 365 | return FALSE; 366 | } 367 | 368 | /** 369 | * @desc - remove product by rowid 370 | * @access private 371 | * @author Iparra 372 | * @param $rowId - product rowid 373 | * @return bool 374 | */ 375 | private function _removeProduct($rowId = '') 376 | { 377 | if(isset($this->_cart[$rowId])) 378 | { 379 | unset($this->_cart[$rowId]); 380 | $this->_updatePriceQty(); 381 | $this->_save(); 382 | return TRUE; 383 | } 384 | //the product not exists 385 | return FALSE; 386 | } 387 | 388 | /** 389 | * @desc - create dir logs if not exists 390 | * @access private 391 | * @author Iparra 392 | */ 393 | private function _createLogDir() 394 | { 395 | if(is_dir("../app")) 396 | { 397 | if(!is_dir("../app/logs")) 398 | { 399 | mkdir("../app/logs"); 400 | } 401 | } 402 | } 403 | 404 | /** 405 | * @desc - remove and update content cart 406 | * @access public 407 | * @author Iparra 408 | * @return bool 409 | */ 410 | public function destroy() 411 | { 412 | $this->_destroy(); 413 | return true; 414 | } 415 | 416 | /** 417 | * @desc - Destroy cart 418 | * @access private 419 | * @author Iparra 420 | */ 421 | private function _destroy() 422 | { 423 | $this->_cart = null; 424 | $this->_save(); 425 | } 426 | } 427 | //End class shoppingCart 428 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unodepiera/phalcon_cart", 3 | "description": "A shopping cart that allows multiple instances to work with PHP Phalcon", 4 | "version": "1.0.0", 5 | "require": { 6 | "php": ">=5.3.0" 7 | }, 8 | "keywords": ["shopping cart Phalcon PHP", "shopping cart for Phalcon PHP", "shopping cart"], 9 | "homepage": "http://uno-de-piera.com/", 10 | "authors": [ 11 | { 12 | "name": "unodepiera", 13 | "email": "unodepiera@uno-de-piera.com" 14 | } 15 | ], 16 | "minimum-stability": "dev" 17 | } --------------------------------------------------------------------------------