├── .gitignore ├── .travis.yml ├── README.md ├── angularjs-deeplink ├── app.js ├── form.html ├── index.html └── list.html ├── base-app-client ├── css │ ├── bootstrap-responsive.min.css │ ├── bootstrap.min.css │ ├── bootswatch.css │ └── font-awesome.min.css ├── img │ └── ajax-loader.gif ├── index.html └── js │ ├── app.js │ └── lib │ ├── angular-resource.min.js │ ├── angular.min.js │ ├── bootstrap.min.js │ ├── bootswatch.js │ ├── jquery.min.js │ └── jquery.smooth-scroll.min.js ├── diretivas ├── ds-card │ ├── app.js │ └── index.html ├── ds-card2 │ ├── app.js │ └── index.html ├── ds-card3 │ ├── app.js │ ├── cardTemplate.html │ └── index.html ├── ds-card4 │ ├── app.js │ ├── cardTemplate.html │ └── index.html └── ds-card5 │ ├── app.js │ ├── boxTemplate.html │ ├── cardTemplate.html │ └── index.html ├── http-example ├── app.js ├── index.html └── listFruits.html ├── node ├── helloWorld.js ├── helloWorldInBrowser.js ├── websocket.html └── websocket.js ├── northSales └── bancoDados │ ├── eer.png │ └── northwind.sql ├── resource-example ├── app.js └── index.html ├── sales-client-1 ├── css │ ├── bootstrap-responsive.min.css │ ├── bootstrap.min.css │ ├── bootswatch.css │ └── font-awesome.min.css ├── img │ └── ajax-loader.gif ├── index.html ├── js │ ├── app.js │ ├── clientesController.js │ ├── funcionariosController.js │ └── lib │ │ ├── angular-resource.min.js │ │ ├── angular.min.js │ │ ├── bootstrap.min.js │ │ ├── bootswatch.js │ │ ├── jquery.min.js │ │ └── jquery.smooth-scroll.min.js └── view │ ├── clientes │ ├── main.html │ └── update.html │ ├── funcionarios │ └── main.html │ └── main.html ├── sales-server ├── .htaccess ├── DB.php ├── Slim │ ├── Environment.php │ ├── Exception │ │ ├── Pass.php │ │ └── Stop.php │ ├── Http │ │ ├── Headers.php │ │ ├── Request.php │ │ ├── Response.php │ │ └── Util.php │ ├── Log.php │ ├── LogWriter.php │ ├── Middleware.php │ ├── Middleware │ │ ├── ContentTypes.php │ │ ├── Flash.php │ │ ├── MethodOverride.php │ │ ├── PrettyExceptions.php │ │ └── SessionCookie.php │ ├── Route.php │ ├── Router.php │ ├── Slim.php │ └── View.php ├── config.php ├── customer.php ├── employee.php └── index.php ├── sales ├── package.json ├── public │ ├── dist │ │ └── build.js │ └── index.html ├── router.js ├── server.js └── src │ └── index.js ├── siteangular ├── gulpfile.js ├── index.html ├── js │ └── script.min.js └── package.json └── test-browserify ├── dist └── build.js ├── index.html ├── package.json └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | # Compiled source # 3 | ################### 4 | *.com 5 | *.class 6 | *.dll 7 | *.exe 8 | *.o 9 | *.so 10 | 11 | # Packages # 12 | ############ 13 | # it's better to unpack these files and commit the raw source 14 | # git has its own built in compression methods 15 | *.7z 16 | *.dmg 17 | *.gz 18 | *.iso 19 | *.jar 20 | *.rar 21 | *.tar 22 | *.zip 23 | 24 | # Logs and databases # 25 | ###################### 26 | *.log 27 | *.sql 28 | *.sqlite 29 | 30 | # OS generated files # 31 | ###################### 32 | .DS_Store 33 | .DS_Store? 34 | ._* 35 | .Spotlight-V100 36 | .Trashes 37 | ehthumbs.db 38 | Thumbs.db 39 | 40 | # NODE # 41 | ######## 42 | .grunt 43 | node_modules 44 | 45 | 46 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.1" 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Livro AngularJS na prática 2 | ============= 3 | 4 | Este é o código fonte do livro AngularJS na prática. -------------------------------------------------------------------------------- /angularjs-deeplink/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app',['ngRoute']); 2 | 3 | 4 | app.config(['$routeProvider',function($routeProvider){ 5 | $routeProvider. 6 | when('/',{controller:'listController', templateUrl:'list.html'}). 7 | when('/edit/:name',{controller:'editController',templateUrl:'form.html'}). 8 | when('/new',{controller:'newController', templateUrl:'form.html'}). 9 | otherwise({redirectTo:'/'}); 10 | }]); 11 | 12 | app.run(['$rootScope',function($rootScope){ 13 | $rootScope.fruits = ["banana","apple","orange"]; 14 | console.log('app.run'); 15 | }]); 16 | 17 | app.controller('listController',function ($scope) { 18 | console.log('listController'); 19 | }); 20 | 21 | app.controller('editController', function ($scope,$location,$routeParams) { 22 | $scope.title = "Editar Fruta"; 23 | $scope.fruit = $routeParams.name; 24 | 25 | $scope.fruitIndex = $scope.fruits.indexOf($scope.fruit); 26 | 27 | $scope.save = function(){ 28 | $scope.fruits[$scope.fruitIndex]=$scope.fruit; 29 | $location.path('/'); 30 | } 31 | }); 32 | 33 | app.controller('newController', function ($scope,$location,$routeParams) { 34 | 35 | $scope.title = "Nova Fruta"; 36 | $scope.fruit = ""; 37 | 38 | $scope.save = function(){ 39 | $scope.fruits.push($scope.fruit); 40 | $location.path('/'); 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /angularjs-deeplink/form.html: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |
3 | 4 | 5 |
6 | Cancel -------------------------------------------------------------------------------- /angularjs-deeplink/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | DeepLinking Example 4 | 5 | 6 | 7 | 8 | 9 |

DeepLink Example

10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /angularjs-deeplink/list.html: -------------------------------------------------------------------------------- 1 |

Fruits ({{fruits.length}})

2 | 5 | New -------------------------------------------------------------------------------- /base-app-client/css/bootswatch.css: -------------------------------------------------------------------------------- 1 | section { 2 | margin-top: 60px; 3 | padding-top: 100px; 4 | } 5 | 6 | /* index */ 7 | 8 | .tooltip-inner { 9 | max-width: 500px; 10 | } 11 | 12 | .hero-unit { 13 | padding-bottom: 5px; 14 | background-color: #F3F3F3; 15 | border: 1px solid #ddd; 16 | text-align: center; 17 | } 18 | 19 | .hero-unit h1, 20 | .hero-unit p { 21 | margin-bottom: 15px; 22 | } 23 | 24 | #social { 25 | display: inline-block; 26 | margin-top: 45px; 27 | text-align: center; 28 | } 29 | 30 | #gh-star { 31 | margin-right: 10px; 32 | } 33 | 34 | .twitter-share-button { 35 | margin-right: 15px; 36 | } 37 | 38 | .rss-button { 39 | width: 40px; 40 | height: 14px; 41 | font-size: 11px; 42 | line-height: 14px; 43 | font-weight: bold; 44 | margin: 0 0 10px; 45 | padding: 2px 5px 2px 4px; 46 | } 47 | 48 | .index h3 { 49 | text-align: center; 50 | font-size: 20px; 51 | } 52 | 53 | #ticker { 54 | margin-top: 40px; 55 | margin-bottom: 10px; 56 | font-size: 14px; 57 | line-height: 1.4; 58 | } 59 | 60 | .about { 61 | margin-top: 40px; 62 | margin-bottom: 40px; 63 | } 64 | 65 | .about > div { 66 | margin-bottom: 20px; 67 | } 68 | 69 | .about h3 { 70 | margin: 0; 71 | text-align: left; 72 | } 73 | 74 | .about i { 75 | margin-right: 8px; 76 | font-size: 1.3em; 77 | } 78 | 79 | #gallery { 80 | padding-top: 60px; 81 | } 82 | 83 | .thumbnail { 84 | margin-bottom: 20px; 85 | background-color: #f3f3f3; 86 | background-color: rgba(0, 0, 0, 0.05); 87 | } 88 | 89 | .thumbnail img { 90 | width: 100%; 91 | -webkit-border-radius: 7px; 92 | -moz-border-radius: 7px; 93 | border-radius: 7px; 94 | } 95 | 96 | .thumbnail .caption { 97 | color: inherit; 98 | } 99 | 100 | .thumbnail .caption p { 101 | overflow: hidden; 102 | text-overflow: ellipsis; 103 | white-space: nowrap; 104 | } 105 | 106 | .thumbnail h3 { 107 | text-align: left; 108 | margin-bottom: 0; 109 | } 110 | 111 | .thumbnail .btn-toolbar { 112 | margin-top: 15px; 113 | text-align: right; 114 | } 115 | 116 | #more { 117 | margin-top: 40px; 118 | margin-bottom: 20px; 119 | text-align: center; 120 | } 121 | 122 | .links { 123 | margin-bottom: 20px; 124 | } 125 | 126 | .links > a { 127 | margin-right: 10px; 128 | } 129 | 130 | .bsa { 131 | float: right; 132 | max-width: 400px; 133 | padding: 0; 134 | } 135 | 136 | body .one .bsa_it_ad { 137 | margin-bottom: -10px; 138 | padding: 25px 25px 15px 25px; 139 | background: none; 140 | border: none; 141 | font-family: inherit; 142 | color: inherit; 143 | } 144 | 145 | body .one .bsa_it_ad .bsa_it_t, 146 | body .one .bsa_it_ad .bsa_it_d { 147 | color: inherit; 148 | font-size: inherit; 149 | } 150 | 151 | body .one .bsa_it_p { 152 | display: none; 153 | } 154 | 155 | .bsap img { 156 | -webkit-border-radius: 0; 157 | -moz-border-radius: 0; 158 | border-radius: 0; 159 | } 160 | 161 | #footer { 162 | margin-bottom: 20px; 163 | } 164 | 165 | #footer .links a { 166 | margin-right: 10px; 167 | } 168 | 169 | @media (max-width: 480px) { 170 | 171 | .hero-unit { 172 | padding: 20px 20px 0; 173 | margin: 0 0 20px; 174 | } 175 | 176 | .hero-unit h1 { 177 | font-size: 36px; 178 | } 179 | 180 | .hero-unit iframe { 181 | margin-right: 0 !important; 182 | } 183 | 184 | #social { 185 | margin-top: 0px; 186 | margin-bottom: 20px; 187 | } 188 | 189 | #social > span { 190 | display: block; 191 | } 192 | 193 | #ticker { 194 | margin-top: 0; 195 | } 196 | 197 | .about { 198 | margin-top: 0; 199 | } 200 | 201 | .about h3 { 202 | margin-top: 30px; 203 | } 204 | 205 | .about p { 206 | margin-bottom: 0; 207 | } 208 | 209 | .thumbnail .btn { 210 | font-size: 15px; 211 | } 212 | 213 | .modal { 214 | position: fixed !important; 215 | top: 25% !important; 216 | } 217 | } 218 | 219 | @media (min-width: 481px) and (max-width: 767px) { 220 | 221 | .hero-unit { 222 | margin-top: 0; 223 | padding: 30px; 224 | } 225 | 226 | .about { 227 | margin-top: 0; 228 | } 229 | } 230 | 231 | @media (max-width: 767px) { 232 | 233 | 234 | section { 235 | padding-top: 20px; 236 | } 237 | 238 | .bsa { 239 | float: none; 240 | } 241 | } 242 | 243 | @media (max-width: 979px) and (min-width: 768px) { 244 | 245 | .index .navbar { 246 | margin-bottom: 0; 247 | } 248 | 249 | .hero-unit { 250 | border-radius: 0; 251 | } 252 | 253 | section { 254 | padding-top: 20px; 255 | } 256 | 257 | .thumbnail .btn { 258 | padding: 6px 10px; 259 | font-size: 14px; 260 | } 261 | } 262 | 263 | @media (min-width: 980px) { 264 | 265 | .index { 266 | padding-top: 40px; 267 | } 268 | 269 | .preview { 270 | padding-top: 100px; 271 | } 272 | } 273 | 274 | /* preview */ 275 | 276 | .subhead { 277 | padding-bottom: 0; 278 | margin-bottom: 9px; 279 | } 280 | 281 | .subhead h1 { 282 | font-size: 54px; 283 | } 284 | 285 | .subhead > div:first-child { 286 | min-height: 200px; 287 | } 288 | 289 | /* subnav */ 290 | 291 | .subnav { 292 | margin-bottom: 60px; 293 | width: 100%; 294 | height: 36px; 295 | background-color: #eeeeee; /* Old browsers */ 296 | background-repeat: repeat-x; /* Repeat the gradient */ 297 | background-image: -moz-linear-gradient(top, #f5f5f5 0%, #eeeeee 100%); /* FF3.6+ */ 298 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(100%,#eeeeee)); /* Chrome,Safari4+ */ 299 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* Chrome 10+,Safari 5.1+ */ 300 | background-image: -ms-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* IE10+ */ 301 | background-image: -o-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* Opera 11.10+ */ 302 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#eeeeee',GradientType=0 ); /* IE6-9 */ 303 | background-image: linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* W3C */ 304 | border: 1px solid #e5e5e5; 305 | -webkit-border-radius: 4px; 306 | -moz-border-radius: 4px; 307 | border-radius: 4px; 308 | } 309 | 310 | .subnav .nav { 311 | margin-bottom: 0; 312 | } 313 | 314 | .subnav .nav > li > a { 315 | margin: 0; 316 | padding-top: 11px; 317 | padding-bottom: 11px; 318 | border-left: 1px solid #f5f5f5; 319 | border-right: 1px solid #e5e5e5; 320 | -webkit-border-radius: 0; 321 | -moz-border-radius: 0; 322 | border-radius: 0; 323 | } 324 | 325 | .subnav .nav > .active > a, 326 | .subnav .nav > .active > a:hover { 327 | padding-left: 13px; 328 | color: #777; 329 | background-color: #e9e9e9; 330 | border-right-color: #ddd; 331 | border-left: 0; 332 | -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 333 | -moz-box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 334 | box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 335 | } 336 | 337 | .subnav .nav > .active > a .caret, 338 | .subnav .nav > .active > a:hover .caret { 339 | border-top-color: #777; 340 | } 341 | 342 | .subnav .nav > li:first-child > a, 343 | .subnav .nav > li:first-child > a:hover { 344 | border-left: 0; 345 | padding-left: 12px; 346 | -webkit-border-radius: 4px 0 0 4px; 347 | -moz-border-radius: 4px 0 0 4px; 348 | border-radius: 4px 0 0 4px; 349 | } 350 | 351 | .subnav .nav > li:last-child > a { 352 | border-right: 0; 353 | } 354 | 355 | .subnav .dropdown-menu { 356 | -webkit-border-radius: 0 0 4px 4px; 357 | -moz-border-radius: 0 0 4px 4px; 358 | border-radius: 0 0 4px 4px; 359 | } 360 | 361 | @media (max-width: 767px) { 362 | 363 | .subnav { 364 | position: static; 365 | top: auto; 366 | z-index: auto; 367 | width: auto; 368 | height: auto; 369 | background: #fff; /* whole background property since we use a background-image for gradient */ 370 | -webkit-box-shadow: none; 371 | -moz-box-shadow: none; 372 | box-shadow: none; 373 | } 374 | 375 | .subnav .nav > li { 376 | float: none; 377 | } 378 | 379 | .subnav .nav > li > a { 380 | border: 0; 381 | } 382 | 383 | .subnav .nav > li + li > a { 384 | border-top: 1px solid #e5e5e5; 385 | } 386 | 387 | .subnav .nav > li:first-child > a, 388 | .subnav .nav > li:first-child > a:hover { 389 | -webkit-border-radius: 4px 4px 0 0; 390 | -moz-border-radius: 4px 4px 0 0; 391 | border-radius: 4px 4px 0 0; 392 | } 393 | } 394 | 395 | @media (min-width: 980px) { 396 | 397 | .subnav-fixed { 398 | position: fixed; 399 | top: 40px; 400 | left: 0; 401 | right: 0; 402 | z-index: 1020; /* 10 less than .navbar-fixed to prevent any overlap */ 403 | border-color: #d5d5d5; 404 | border-width: 0 0 1px; /* drop the border on the fixed edges */ 405 | -webkit-border-radius: 0; 406 | -moz-border-radius: 0; 407 | border-radius: 0; 408 | -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 409 | -moz-box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 410 | box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 411 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */ 412 | } 413 | 414 | .subnav-fixed .nav { 415 | width: 938px; 416 | margin: 0 auto; 417 | padding: 0 1px; 418 | } 419 | 420 | .subnav .nav > li:first-child > a, 421 | .subnav .nav > li:first-child > a:hover { 422 | -webkit-border-radius: 0; 423 | -moz-border-radius: 0; 424 | border-radius: 0; 425 | } 426 | } 427 | 428 | @media (min-width: 1210px) { 429 | 430 | .subnav-fixed .nav { 431 | width: 1168px; /* 2px less to account for left/right borders being removed when in fixed mode */ 432 | } 433 | } -------------------------------------------------------------------------------- /base-app-client/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 3.0.2 3 | * the iconic font designed for use with Twitter Bootstrap 4 | * ------------------------------------------------------- 5 | * The full suite of pictographic icons, examples, and documentation 6 | * can be found at: http://fortawesome.github.com/Font-Awesome/ 7 | * 8 | * License 9 | * ------------------------------------------------------- 10 | * - The Font Awesome font is licensed under the SIL Open Font License - http://scripts.sil.org/OFL 11 | * - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License - 12 | * http://opensource.org/licenses/mit-license.html 13 | * - The Font Awesome pictograms are licensed under the CC BY 3.0 License - http://creativecommons.org/licenses/by/3.0/ 14 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: 15 | * "Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome" 16 | 17 | * Contact 18 | * ------------------------------------------------------- 19 | * Email: dave@davegandy.com 20 | * Twitter: http://twitter.com/fortaweso_me 21 | * Work: Lead Product Designer @ http://kyruus.com 22 | */ 23 | 24 | @font-face{ 25 | font-family:'FontAwesome'; 26 | src:url('../font/fontawesome-webfont.eot?v=3.0.1'); 27 | src:url('../font/fontawesome-webfont.eot?#iefix&v=3.0.1') format('embedded-opentype'), 28 | url('../font/fontawesome-webfont.woff?v=3.0.1') format('woff'), 29 | url('../font/fontawesome-webfont.ttf?v=3.0.1') format('truetype'); 30 | font-weight:normal; 31 | font-style:normal } 32 | 33 | [class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}a [class^="icon-"],a [class*=" icon-"]{display:inline-block}.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}.btn [class^="icon-"],.nav [class^="icon-"],.btn [class*=" icon-"],.nav [class*=" icon-"]{display:inline}.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em}li [class^="icon-"],.nav li [class^="icon-"],li [class*=" icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center}li [class^="icon-"].icon-large,.nav li [class^="icon-"].icon-large,li [class*=" icon-"].icon-large,.nav li [class*=" icon-"].icon-large{width:1.5625em}ul.icons{list-style-type:none;text-indent:-0.75em}ul.icons li [class^="icon-"],ul.icons li [class*=" icon-"]{width:.75em}.icon-muted{color:#eee}.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.pull-right{float:right}.pull-left{float:left}[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}@-moz-document url-prefix(){.icon-spin{height:.9em}.btn .icon-spin{height:auto}.icon-spin.icon-large{height:1.25em}.btn .icon-spin.icon-large{height:.75em}}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-repeat:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-share-alt:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope-alt:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-undo:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-reply:before{content:"\f112"}.icon-github-alt:before{content:"\f113"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"} -------------------------------------------------------------------------------- /base-app-client/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielschmitz/angularjs-codigos/e500e48a1ef8f2ce8f93168d161b414ad9ee1b53/base-app-client/img/ajax-loader.gif -------------------------------------------------------------------------------- /base-app-client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Base App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 37 | 38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /base-app-client/js/app.js: -------------------------------------------------------------------------------- 1 | $app = angular.module('app',['ngResource']); 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /base-app-client/js/lib/angular-resource.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.1.4 3 | (c) 2010-2012 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(B,f,x){'use strict';f.module("ngResource",["ng"]).factory("$resource",["$http","$parse",function(y,z){function v(g,c){this.template=g+"#";this.defaults=c||{};this.urlParams={}}function w(g,c,d){function j(e,b){var p={},b=q({},c,b);k(b,function(a,b){l(a)&&(a=a());var h;a.charAt&&a.charAt(0)=="@"?(h=a.substr(1),h=z(h)(e)):h=a;p[b]=h});return p}function b(b){u(b||{},this)}var m=new v(g),d=q({},A,d);k(d,function(e,c){e.method=f.uppercase(e.method);var p=e.method=="POST"||e.method=="PUT"||e.method== 7 | "PATCH";b[c]=function(a,c,h,g){function f(){i.$resolved=!0}var n={},d,o=r,s=null;switch(arguments.length){case 4:s=g,o=h;case 3:case 2:if(l(c)){if(l(a)){o=a;s=c;break}o=c;s=h}else{n=a;d=c;o=h;break}case 1:l(a)?o=a:p?d=a:n=a;break;case 0:break;default:throw"Expected between 0-4 arguments [params, data, success, error], got "+arguments.length+" arguments.";}var i=this instanceof b?this:e.isArray?[]:new b(d),t={};k(e,function(a,b){b!="params"&&b!="isArray"&&(t[b]=u(a))});t.data=d;m.setUrlParams(t,q({}, 8 | j(d,e.params||{}),n),e.url);n=y(t);i.$resolved=!1;n.then(f,f);i.$then=n.then(function(a){var c=a.data,h=i.$then,d=i.$resolved;if(c)e.isArray?(i.length=0,k(c,function(a){i.push(new b(a))})):(u(c,i),i.$then=h,i.$resolved=d);(o||r)(i,a.headers);a.resource=i;return a},s).then;return i};b.prototype["$"+c]=function(a,e,h){var d=j(this),f=r,g;switch(arguments.length){case 3:d=a;f=e;g=h;break;case 2:case 1:l(a)?(f=a,g=e):(d=a,f=e||r);case 0:break;default:throw"Expected between 1-3 arguments [params, success, error], got "+ 9 | arguments.length+" arguments.";}b[c].call(this,d,p?this:x,f,g)}});b.bind=function(b){return w(g,q({},c,b),d)};return b}var A={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},r=f.noop,k=f.forEach,q=f.extend,u=f.copy,l=f.isFunction;v.prototype={setUrlParams:function(g,c,d){var j=this,b=d||j.template,m,e,l=j.urlParams={};k(b.split(/\W/),function(c){c&&RegExp("(^|[^\\\\]):"+c+"(\\W|$)").test(b)&&(l[c]=!0)});b=b.replace(/\\:/g, 10 | ":");c=c||{};k(j.urlParams,function(d,a){m=c.hasOwnProperty(a)?c[a]:j.defaults[a];f.isDefined(m)&&m!==null?(e=encodeURIComponent(m).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),b=b.replace(RegExp(":"+a+"(\\W|$)","g"),e+"$1")):b=b.replace(RegExp("(/?):"+a+"(\\W|$)","g"),function(a,b,c){return c.charAt(0)=="/"?c:b+c})});g.url=b.replace(/\/?#$/,"").replace(/\/*$/,"");k(c,function(b, 11 | a){if(!j.urlParams[a])g.params=g.params||{},g.params[a]=b})}};return w}])})(window,window.angular); 12 | -------------------------------------------------------------------------------- /base-app-client/js/lib/bootswatch.js: -------------------------------------------------------------------------------- 1 | $('a[rel=tooltip]').tooltip({ 2 | 'placement': 'bottom' 3 | }); 4 | 5 | 6 | $('.navbar a, .subnav a').smoothScroll(); 7 | 8 | 9 | (function ($) { 10 | 11 | $(function(){ 12 | 13 | // fix sub nav on scroll 14 | var $win = $(window), 15 | $body = $('body'), 16 | $nav = $('.subnav'), 17 | navHeight = $('.navbar').first().height(), 18 | subnavHeight = $('.subnav').first().height(), 19 | subnavTop = $('.subnav').length && $('.subnav').offset().top - navHeight, 20 | marginTop = parseInt($body.css('margin-top'), 10); 21 | isFixed = 0; 22 | 23 | processScroll(); 24 | 25 | $win.on('scroll', processScroll); 26 | 27 | function processScroll() { 28 | var i, scrollTop = $win.scrollTop(); 29 | 30 | if (scrollTop >= subnavTop && !isFixed) { 31 | isFixed = 1; 32 | $nav.addClass('subnav-fixed'); 33 | $body.css('margin-top', marginTop + subnavHeight + 'px'); 34 | } else if (scrollTop <= subnavTop && isFixed) { 35 | isFixed = 0; 36 | $nav.removeClass('subnav-fixed'); 37 | $body.css('margin-top', marginTop + 'px'); 38 | } 39 | } 40 | 41 | }); 42 | 43 | })(window.jQuery); -------------------------------------------------------------------------------- /base-app-client/js/lib/jquery.smooth-scroll.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Smooth Scroll - v1.4.10 - 2013-03-02 3 | * https://github.com/kswedberg/jquery-smooth-scroll 4 | * Copyright (c) 2013 Karl Swedberg 5 | * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT) 6 | */ 7 | (function(l){function t(l){return l.replace(/(:|\.)/g,"\\$1")}var e="1.4.10",o={exclude:[],excludeWithin:[],offset:0,direction:"top",scrollElement:null,scrollTarget:null,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficent:2},r=function(t){var e=[],o=!1,r=t.dir&&"left"==t.dir?"scrollLeft":"scrollTop";return this.each(function(){if(this!=document&&this!=window){var t=l(this);t[r]()>0?e.push(this):(t[r](1),o=t[r]()>0,o&&e.push(this),t[r](0))}}),e.length||this.each(function(){"BODY"===this.nodeName&&(e=[this])}),"first"===t.el&&e.length>1&&(e=[e[0]]),e};l.fn.extend({scrollable:function(l){var t=r.call(this,{dir:l});return this.pushStack(t)},firstScrollable:function(l){var t=r.call(this,{el:"first",dir:l});return this.pushStack(t)},smoothScroll:function(e){e=e||{};var o=l.extend({},l.fn.smoothScroll.defaults,e),r=l.smoothScroll.filterPath(location.pathname);return this.unbind("click.smoothscroll").bind("click.smoothscroll",function(e){var n=this,s=l(this),c=o.exclude,i=o.excludeWithin,a=0,f=0,h=!0,u={},d=location.hostname===n.hostname||!n.hostname,m=o.scrollTarget||(l.smoothScroll.filterPath(n.pathname)||r)===r,p=t(n.hash);if(o.scrollTarget||d&&m&&p){for(;h&&c.length>a;)s.is(t(c[a++]))&&(h=!1);for(;h&&i.length>f;)s.closest(i[f++]).length&&(h=!1)}else h=!1;h&&(e.preventDefault(),l.extend(u,o,{scrollTarget:o.scrollTarget||p,link:n}),l.smoothScroll(u))}),this}}),l.smoothScroll=function(t,e){var o,r,n,s,c=0,i="offset",a="scrollTop",f={},h={};"number"==typeof t?(o=l.fn.smoothScroll.defaults,n=t):(o=l.extend({},l.fn.smoothScroll.defaults,t||{}),o.scrollElement&&(i="position","static"==o.scrollElement.css("position")&&o.scrollElement.css("position","relative"))),o=l.extend({link:null},o),a="left"==o.direction?"scrollLeft":a,o.scrollElement?(r=o.scrollElement,c=r[a]()):r=l("html, body").firstScrollable(),o.beforeScroll.call(r,o),n="number"==typeof t?t:e||l(o.scrollTarget)[i]()&&l(o.scrollTarget)[i]()[o.direction]||0,f[a]=n+c+o.offset,s=o.speed,"auto"===s&&(s=f[a]||r.scrollTop(),s/=o.autoCoefficent),h={duration:s,easing:o.easing,complete:function(){o.afterScroll.call(o.link,o)}},o.step&&(h.step=o.step),r.length?r.stop().animate(f,h):o.afterScroll.call(o.link,o)},l.smoothScroll.version=e,l.smoothScroll.filterPath=function(l){return l.replace(/^\//,"").replace(/(index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},l.fn.smoothScroll.defaults=o})(jQuery); -------------------------------------------------------------------------------- /diretivas/ds-card/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', []); 2 | 3 | app.controller('appController', function ($scope) { 4 | $scope.usuario = { 5 | name:"Daniel", 6 | email:"daniel@gmail.com" 7 | }; 8 | 9 | }); 10 | 11 | app.directive('dsCard',function(){ 12 | return { 13 | template: "Nome: {{usuario.name}}
{{usuario.email}}" 14 | }; 15 | }); -------------------------------------------------------------------------------- /diretivas/ds-card/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /diretivas/ds-card2/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', []); 2 | 3 | app.controller('appController', function ($scope) { 4 | 5 | 6 | }); 7 | 8 | app.directive('dsCard',function(){ 9 | return { 10 | restrict: 'E', 11 | scope:{ 12 | name : '@', 13 | email : '@' 14 | }, 15 | template: "Nome: {{name}}
{{email}}" 16 | }; 17 | }); -------------------------------------------------------------------------------- /diretivas/ds-card2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello World 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /diretivas/ds-card3/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', []); 2 | 3 | app.controller('appController', function ($scope) { 4 | 5 | 6 | }); 7 | 8 | app.directive('dsCard',function(){ 9 | return { 10 | restrict: 'E', 11 | scope:{ 12 | name : '@', 13 | email : '@' 14 | }, 15 | templateUrl: "cardTemplate.html" 16 | }; 17 | }); -------------------------------------------------------------------------------- /diretivas/ds-card3/cardTemplate.html: -------------------------------------------------------------------------------- 1 |
2 |

{{name}}

3 |

{{email}}

4 |
-------------------------------------------------------------------------------- /diretivas/ds-card3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello World 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 |
23 | 24 |
25 | 26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /diretivas/ds-card4/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', []); 2 | 3 | app.controller('appController', function ($scope) { 4 | 5 | $scope.users = [ 6 | {name:'daniel',email:'daniel@gmail.com'}, 7 | {name:'jose',email:'jose@gmail.com'}, 8 | {name:'pedro',email:'pedro@gmail.com'} 9 | ] 10 | 11 | $scope.user = {name:'',email:''}; 12 | 13 | $scope.clickAdd = function(){ 14 | $scope.users.push($scope.user); 15 | } 16 | 17 | }); 18 | 19 | app.directive('dsCard',function(){ 20 | return { 21 | restrict: 'E', 22 | scope:{ 23 | name : '@', 24 | email : '@' 25 | }, 26 | templateUrl: "cardTemplate.html" 27 | }; 28 | }); -------------------------------------------------------------------------------- /diretivas/ds-card4/cardTemplate.html: -------------------------------------------------------------------------------- 1 |
2 |

{{name}}

3 |

{{email}}

4 |
-------------------------------------------------------------------------------- /diretivas/ds-card4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello World 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 | 29 |
30 | 31 |
32 | 33 |

34 | 35 | 36 | 37 | 38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /diretivas/ds-card5/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', []); 2 | 3 | app.controller('appController', function ($scope) { 4 | 5 | $scope.users = [ 6 | {name:'daniel',email:'daniel@gmail.com'}, 7 | {name:'jose',email:'jose@gmail.com'}, 8 | {name:'pedro',email:'pedro@gmail.com'} 9 | ] 10 | 11 | $scope.user = {name:'',email:''}; 12 | 13 | $scope.clickAdd = function(){ 14 | $scope.users.push($scope.user); 15 | } 16 | 17 | }); 18 | 19 | app.directive('dsCard',function(){ 20 | return { 21 | restrict: 'E', 22 | scope:{ 23 | name : '@', 24 | email : '@' 25 | }, 26 | templateUrl: "cardTemplate.html" 27 | }; 28 | }); 29 | 30 | app.directive('dsBox',function(){ 31 | return { 32 | restrict: 'E', 33 | transclude: true, 34 | scope:{ 35 | title : '@' 36 | }, 37 | templateUrl: "boxTemplate.html" 38 | }; 39 | }); -------------------------------------------------------------------------------- /diretivas/ds-card5/boxTemplate.html: -------------------------------------------------------------------------------- 1 |
2 |
{{title}}
3 |
4 |
5 |
-------------------------------------------------------------------------------- /diretivas/ds-card5/cardTemplate.html: -------------------------------------------------------------------------------- 1 |
2 |

{{name}}

3 |

{{email}}

4 |
-------------------------------------------------------------------------------- /diretivas/ds-card5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello World 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /http-example/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app',[]); 2 | 3 | app.controller('appController',function ($scope,$http){ 4 | $scope.fruits = Array(); 5 | 6 | $scope.getData = function(){ 7 | $http.get("listFruits.html").success(function(data){ 8 | $scope.fruits = data.fruits; 9 | console.log($scope.fruits); 10 | }).error(function(data){ 11 | alert("Error..."); 12 | console.log(data); 13 | }); 14 | } 15 | }); -------------------------------------------------------------------------------- /http-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 |

Fruits

10 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /http-example/listFruits.html: -------------------------------------------------------------------------------- 1 | {"fruits":[ 2 | { 3 | "id": 1, 4 | "name": "Apple", 5 | "color": "Red" 6 | }, 7 | { 8 | "id": 2, 9 | "name": "Banana", 10 | "color": "Yellow" 11 | }, 12 | { 13 | "id": 3, 14 | "name": "watermelon", 15 | "color": "Green" 16 | }, 17 | { 18 | "id": 4, 19 | "name": "Orange", 20 | "color": "Orange" 21 | } 22 | ]} -------------------------------------------------------------------------------- /node/helloWorld.js: -------------------------------------------------------------------------------- 1 | console.log("Hello World"); -------------------------------------------------------------------------------- /node/helloWorldInBrowser.js: -------------------------------------------------------------------------------- 1 | var http = require("http"); 2 | var server = http.createServer(function (request, response) { 3 | response.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"}); 4 | response.write("Olá Mundo!!"); 5 | response.end(); 6 | }); 7 | server.listen(8000); 8 | -------------------------------------------------------------------------------- /node/websocket.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularJS na pratica - SOCKET.IO por Douglas Lira 6 | 7 | 8 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /node/websocket.js: -------------------------------------------------------------------------------- 1 | var io = require('socket.io').listen(8000); 2 | io.sockets.on('connection', function (socket) { 3 | socket.on('emissor', function(texto) { 4 | io.sockets.emit('recpetor', texto); 5 | }); 6 | }); -------------------------------------------------------------------------------- /northSales/bancoDados/eer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielschmitz/angularjs-codigos/e500e48a1ef8f2ce8f93168d161b414ad9ee1b53/northSales/bancoDados/eer.png -------------------------------------------------------------------------------- /resource-example/app.js: -------------------------------------------------------------------------------- 1 | var $app = angular.module('app',['ngResource']); 2 | 3 | $app.controller("phoneController",function ($scope,$resource){ 4 | 5 | var Phone = $resource("/phones/:phoneId"); 6 | 7 | $scope.getPhoneById = function(){ 8 | Phone.get({phoneId:$scope.idPhone},function(data){ 9 | $scope.phone=data; 10 | }); 11 | } 12 | 13 | $scope.getPhones = function(){ 14 | Phone.query(function (data){ 15 | scope.phones = data; 16 | }); 17 | } 18 | 19 | 20 | $scope.savePhone = function(){ 21 | p = new Phone(); 22 | p.number="1111-2222" 23 | p.$save(); 24 | } 25 | 26 | $scope.deletePhone = function(){ 27 | Phone.delete({phoneId:10}); 28 | } 29 | 30 | }); -------------------------------------------------------------------------------- /resource-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Lista de compras 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /sales-client-1/css/bootswatch.css: -------------------------------------------------------------------------------- 1 | section { 2 | margin-top: 60px; 3 | padding-top: 100px; 4 | } 5 | 6 | /* index */ 7 | 8 | .tooltip-inner { 9 | max-width: 500px; 10 | } 11 | 12 | .hero-unit { 13 | padding-bottom: 5px; 14 | background-color: #F3F3F3; 15 | border: 1px solid #ddd; 16 | text-align: center; 17 | } 18 | 19 | .hero-unit h1, 20 | .hero-unit p { 21 | margin-bottom: 15px; 22 | } 23 | 24 | #social { 25 | display: inline-block; 26 | margin-top: 45px; 27 | text-align: center; 28 | } 29 | 30 | #gh-star { 31 | margin-right: 10px; 32 | } 33 | 34 | .twitter-share-button { 35 | margin-right: 15px; 36 | } 37 | 38 | .rss-button { 39 | width: 40px; 40 | height: 14px; 41 | font-size: 11px; 42 | line-height: 14px; 43 | font-weight: bold; 44 | margin: 0 0 10px; 45 | padding: 2px 5px 2px 4px; 46 | } 47 | 48 | .index h3 { 49 | text-align: center; 50 | font-size: 20px; 51 | } 52 | 53 | #ticker { 54 | margin-top: 40px; 55 | margin-bottom: 10px; 56 | font-size: 14px; 57 | line-height: 1.4; 58 | } 59 | 60 | .about { 61 | margin-top: 40px; 62 | margin-bottom: 40px; 63 | } 64 | 65 | .about > div { 66 | margin-bottom: 20px; 67 | } 68 | 69 | .about h3 { 70 | margin: 0; 71 | text-align: left; 72 | } 73 | 74 | .about i { 75 | margin-right: 8px; 76 | font-size: 1.3em; 77 | } 78 | 79 | #gallery { 80 | padding-top: 60px; 81 | } 82 | 83 | .thumbnail { 84 | margin-bottom: 20px; 85 | background-color: #f3f3f3; 86 | background-color: rgba(0, 0, 0, 0.05); 87 | } 88 | 89 | .thumbnail img { 90 | width: 100%; 91 | -webkit-border-radius: 7px; 92 | -moz-border-radius: 7px; 93 | border-radius: 7px; 94 | } 95 | 96 | .thumbnail .caption { 97 | color: inherit; 98 | } 99 | 100 | .thumbnail .caption p { 101 | overflow: hidden; 102 | text-overflow: ellipsis; 103 | white-space: nowrap; 104 | } 105 | 106 | .thumbnail h3 { 107 | text-align: left; 108 | margin-bottom: 0; 109 | } 110 | 111 | .thumbnail .btn-toolbar { 112 | margin-top: 15px; 113 | text-align: right; 114 | } 115 | 116 | #more { 117 | margin-top: 40px; 118 | margin-bottom: 20px; 119 | text-align: center; 120 | } 121 | 122 | .links { 123 | margin-bottom: 20px; 124 | } 125 | 126 | .links > a { 127 | margin-right: 10px; 128 | } 129 | 130 | .bsa { 131 | float: right; 132 | max-width: 400px; 133 | padding: 0; 134 | } 135 | 136 | body .one .bsa_it_ad { 137 | margin-bottom: -10px; 138 | padding: 25px 25px 15px 25px; 139 | background: none; 140 | border: none; 141 | font-family: inherit; 142 | color: inherit; 143 | } 144 | 145 | body .one .bsa_it_ad .bsa_it_t, 146 | body .one .bsa_it_ad .bsa_it_d { 147 | color: inherit; 148 | font-size: inherit; 149 | } 150 | 151 | body .one .bsa_it_p { 152 | display: none; 153 | } 154 | 155 | .bsap img { 156 | -webkit-border-radius: 0; 157 | -moz-border-radius: 0; 158 | border-radius: 0; 159 | } 160 | 161 | #footer { 162 | margin-bottom: 20px; 163 | } 164 | 165 | #footer .links a { 166 | margin-right: 10px; 167 | } 168 | 169 | @media (max-width: 480px) { 170 | 171 | .hero-unit { 172 | padding: 20px 20px 0; 173 | margin: 0 0 20px; 174 | } 175 | 176 | .hero-unit h1 { 177 | font-size: 36px; 178 | } 179 | 180 | .hero-unit iframe { 181 | margin-right: 0 !important; 182 | } 183 | 184 | #social { 185 | margin-top: 0px; 186 | margin-bottom: 20px; 187 | } 188 | 189 | #social > span { 190 | display: block; 191 | } 192 | 193 | #ticker { 194 | margin-top: 0; 195 | } 196 | 197 | .about { 198 | margin-top: 0; 199 | } 200 | 201 | .about h3 { 202 | margin-top: 30px; 203 | } 204 | 205 | .about p { 206 | margin-bottom: 0; 207 | } 208 | 209 | .thumbnail .btn { 210 | font-size: 15px; 211 | } 212 | 213 | .modal { 214 | position: fixed !important; 215 | top: 25% !important; 216 | } 217 | } 218 | 219 | @media (min-width: 481px) and (max-width: 767px) { 220 | 221 | .hero-unit { 222 | margin-top: 0; 223 | padding: 30px; 224 | } 225 | 226 | .about { 227 | margin-top: 0; 228 | } 229 | } 230 | 231 | @media (max-width: 767px) { 232 | 233 | 234 | section { 235 | padding-top: 20px; 236 | } 237 | 238 | .bsa { 239 | float: none; 240 | } 241 | } 242 | 243 | @media (max-width: 979px) and (min-width: 768px) { 244 | 245 | .index .navbar { 246 | margin-bottom: 0; 247 | } 248 | 249 | .hero-unit { 250 | border-radius: 0; 251 | } 252 | 253 | section { 254 | padding-top: 20px; 255 | } 256 | 257 | .thumbnail .btn { 258 | padding: 6px 10px; 259 | font-size: 14px; 260 | } 261 | } 262 | 263 | @media (min-width: 980px) { 264 | 265 | .index { 266 | padding-top: 40px; 267 | } 268 | 269 | .preview { 270 | padding-top: 100px; 271 | } 272 | } 273 | 274 | /* preview */ 275 | 276 | .subhead { 277 | padding-bottom: 0; 278 | margin-bottom: 9px; 279 | } 280 | 281 | .subhead h1 { 282 | font-size: 54px; 283 | } 284 | 285 | .subhead > div:first-child { 286 | min-height: 200px; 287 | } 288 | 289 | /* subnav */ 290 | 291 | .subnav { 292 | margin-bottom: 60px; 293 | width: 100%; 294 | height: 36px; 295 | background-color: #eeeeee; /* Old browsers */ 296 | background-repeat: repeat-x; /* Repeat the gradient */ 297 | background-image: -moz-linear-gradient(top, #f5f5f5 0%, #eeeeee 100%); /* FF3.6+ */ 298 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(100%,#eeeeee)); /* Chrome,Safari4+ */ 299 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* Chrome 10+,Safari 5.1+ */ 300 | background-image: -ms-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* IE10+ */ 301 | background-image: -o-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* Opera 11.10+ */ 302 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#eeeeee',GradientType=0 ); /* IE6-9 */ 303 | background-image: linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* W3C */ 304 | border: 1px solid #e5e5e5; 305 | -webkit-border-radius: 4px; 306 | -moz-border-radius: 4px; 307 | border-radius: 4px; 308 | } 309 | 310 | .subnav .nav { 311 | margin-bottom: 0; 312 | } 313 | 314 | .subnav .nav > li > a { 315 | margin: 0; 316 | padding-top: 11px; 317 | padding-bottom: 11px; 318 | border-left: 1px solid #f5f5f5; 319 | border-right: 1px solid #e5e5e5; 320 | -webkit-border-radius: 0; 321 | -moz-border-radius: 0; 322 | border-radius: 0; 323 | } 324 | 325 | .subnav .nav > .active > a, 326 | .subnav .nav > .active > a:hover { 327 | padding-left: 13px; 328 | color: #777; 329 | background-color: #e9e9e9; 330 | border-right-color: #ddd; 331 | border-left: 0; 332 | -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 333 | -moz-box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 334 | box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 335 | } 336 | 337 | .subnav .nav > .active > a .caret, 338 | .subnav .nav > .active > a:hover .caret { 339 | border-top-color: #777; 340 | } 341 | 342 | .subnav .nav > li:first-child > a, 343 | .subnav .nav > li:first-child > a:hover { 344 | border-left: 0; 345 | padding-left: 12px; 346 | -webkit-border-radius: 4px 0 0 4px; 347 | -moz-border-radius: 4px 0 0 4px; 348 | border-radius: 4px 0 0 4px; 349 | } 350 | 351 | .subnav .nav > li:last-child > a { 352 | border-right: 0; 353 | } 354 | 355 | .subnav .dropdown-menu { 356 | -webkit-border-radius: 0 0 4px 4px; 357 | -moz-border-radius: 0 0 4px 4px; 358 | border-radius: 0 0 4px 4px; 359 | } 360 | 361 | @media (max-width: 767px) { 362 | 363 | .subnav { 364 | position: static; 365 | top: auto; 366 | z-index: auto; 367 | width: auto; 368 | height: auto; 369 | background: #fff; /* whole background property since we use a background-image for gradient */ 370 | -webkit-box-shadow: none; 371 | -moz-box-shadow: none; 372 | box-shadow: none; 373 | } 374 | 375 | .subnav .nav > li { 376 | float: none; 377 | } 378 | 379 | .subnav .nav > li > a { 380 | border: 0; 381 | } 382 | 383 | .subnav .nav > li + li > a { 384 | border-top: 1px solid #e5e5e5; 385 | } 386 | 387 | .subnav .nav > li:first-child > a, 388 | .subnav .nav > li:first-child > a:hover { 389 | -webkit-border-radius: 4px 4px 0 0; 390 | -moz-border-radius: 4px 4px 0 0; 391 | border-radius: 4px 4px 0 0; 392 | } 393 | } 394 | 395 | @media (min-width: 980px) { 396 | 397 | .subnav-fixed { 398 | position: fixed; 399 | top: 40px; 400 | left: 0; 401 | right: 0; 402 | z-index: 1020; /* 10 less than .navbar-fixed to prevent any overlap */ 403 | border-color: #d5d5d5; 404 | border-width: 0 0 1px; /* drop the border on the fixed edges */ 405 | -webkit-border-radius: 0; 406 | -moz-border-radius: 0; 407 | border-radius: 0; 408 | -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 409 | -moz-box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 410 | box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 411 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */ 412 | } 413 | 414 | .subnav-fixed .nav { 415 | width: 938px; 416 | margin: 0 auto; 417 | padding: 0 1px; 418 | } 419 | 420 | .subnav .nav > li:first-child > a, 421 | .subnav .nav > li:first-child > a:hover { 422 | -webkit-border-radius: 0; 423 | -moz-border-radius: 0; 424 | border-radius: 0; 425 | } 426 | } 427 | 428 | @media (min-width: 1210px) { 429 | 430 | .subnav-fixed .nav { 431 | width: 1168px; /* 2px less to account for left/right borders being removed when in fixed mode */ 432 | } 433 | } 434 | 435 | 436 | -------------------------------------------------------------------------------- /sales-client-1/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 3.0.2 3 | * the iconic font designed for use with Twitter Bootstrap 4 | * ------------------------------------------------------- 5 | * The full suite of pictographic icons, examples, and documentation 6 | * can be found at: http://fortawesome.github.com/Font-Awesome/ 7 | * 8 | * License 9 | * ------------------------------------------------------- 10 | * - The Font Awesome font is licensed under the SIL Open Font License - http://scripts.sil.org/OFL 11 | * - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License - 12 | * http://opensource.org/licenses/mit-license.html 13 | * - The Font Awesome pictograms are licensed under the CC BY 3.0 License - http://creativecommons.org/licenses/by/3.0/ 14 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: 15 | * "Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome" 16 | 17 | * Contact 18 | * ------------------------------------------------------- 19 | * Email: dave@davegandy.com 20 | * Twitter: http://twitter.com/fortaweso_me 21 | * Work: Lead Product Designer @ http://kyruus.com 22 | */ 23 | 24 | @font-face{ 25 | font-family:'FontAwesome'; 26 | src:url('../font/fontawesome-webfont.eot?v=3.0.1'); 27 | src:url('../font/fontawesome-webfont.eot?#iefix&v=3.0.1') format('embedded-opentype'), 28 | url('../font/fontawesome-webfont.woff?v=3.0.1') format('woff'), 29 | url('../font/fontawesome-webfont.ttf?v=3.0.1') format('truetype'); 30 | font-weight:normal; 31 | font-style:normal } 32 | 33 | [class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}a [class^="icon-"],a [class*=" icon-"]{display:inline-block}.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}.btn [class^="icon-"],.nav [class^="icon-"],.btn [class*=" icon-"],.nav [class*=" icon-"]{display:inline}.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em}li [class^="icon-"],.nav li [class^="icon-"],li [class*=" icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center}li [class^="icon-"].icon-large,.nav li [class^="icon-"].icon-large,li [class*=" icon-"].icon-large,.nav li [class*=" icon-"].icon-large{width:1.5625em}ul.icons{list-style-type:none;text-indent:-0.75em}ul.icons li [class^="icon-"],ul.icons li [class*=" icon-"]{width:.75em}.icon-muted{color:#eee}.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.pull-right{float:right}.pull-left{float:left}[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}@-moz-document url-prefix(){.icon-spin{height:.9em}.btn .icon-spin{height:auto}.icon-spin.icon-large{height:1.25em}.btn .icon-spin.icon-large{height:.75em}}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-repeat:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-share-alt:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope-alt:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-undo:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-reply:before{content:"\f112"}.icon-github-alt:before{content:"\f113"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"} -------------------------------------------------------------------------------- /sales-client-1/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielschmitz/angularjs-codigos/e500e48a1ef8f2ce8f93168d161b414ad9ee1b53/sales-client-1/img/ajax-loader.gif -------------------------------------------------------------------------------- /sales-client-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sales App 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 46 | 47 | 48 |
49 | 50 | 51 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /sales-client-1/js/app.js: -------------------------------------------------------------------------------- 1 | //URL de acesso ao servidor RESTful 2 | //SERVER_URL = "http://localhost/sales-server"; 3 | 4 | //Novo server_url para o cloud9 5 | SERVER_URL = "https://demo-project-c9-danielschmitz.c9.io/angular/livro-angular/sales-server"; 6 | 7 | //Criação ao $app que é o modulo que representa toda a aplicação 8 | var $app = angular.module('app',['ngRoute']); 9 | 10 | $app.config(['$routeProvider','$httpProvider',function($routeProvider,$httpProvider){ 11 | 12 | //Configura o route provider 13 | $routeProvider. 14 | when('/',{templateUrl:'view/main.html'}). 15 | when('/clientes',{templateUrl:'view/clientes/main.html',controller:'clientesController'}). 16 | when('/clientes/new',{templateUrl:'view/clientes/update.html',controller:'clientesController'}). 17 | when('/cliente/:id',{templateUrl:'view/clientes/update.html',controller:'clientesController'}). 18 | when('/funcionarios',{templateUrl:'view/funcionarios/main.html',controller:'funcionariosController'}). 19 | otherwise({redirectTo:'/'}); 20 | 21 | //configura o RESPONSE interceptor, usado para exibir o ícone de acesso ao servidor 22 | // e a exibir uma mensagem de erro caso o servidor retorne algum erro 23 | $httpProvider.interceptors.push(function($q,$rootScope) { 24 | return function(promise) { 25 | //Always disable loader 26 | $rootScope.hideLoader(); 27 | return promise.then(function(response) { 28 | // do something on success 29 | return(response); 30 | }, function(response) { 31 | // do something on error 32 | $data = response.data; 33 | $error = $data.error; 34 | console.error($data); 35 | if ($error && $error.text) 36 | alert("ERROR: " + $error.text); 37 | else{ 38 | if (response.status=404) 39 | alert("Erro ao acessar servidor. Página não encontrada. Veja o log de erros para maiores detalhes"); 40 | else 41 | alert("ERROR! See log console"); 42 | } 43 | return $q.reject(response); 44 | }); 45 | } 46 | }); 47 | }]); 48 | 49 | $app.run(['$rootScope',function($rootScope){ 50 | 51 | //Uma flag que define se o ícone de acesso ao servidor deve estar ativado 52 | $rootScope.showLoaderFlag = false; 53 | 54 | //Força que o ícone de acesso ao servidor seja ativado 55 | $rootScope.showLoader=function(){ 56 | $rootScope.showLoaderFlag=true; 57 | } 58 | //Força que o ícone de acesso ao servidor seja desativado 59 | $rootScope.hideLoader=function(){ 60 | $rootScope.showLoaderFlag=false; 61 | } 62 | 63 | //Método que retorna a URL completa de acesso ao servidor. 64 | // Evita usar concatenação 65 | $rootScope.server=function(url){ 66 | return SERVER_URL + url; 67 | } 68 | 69 | }]); 70 | 71 | //We already have a limitTo filter built-in to angular, 72 | //let's make a startFrom filter 73 | $app.filter('startFrom', function() { 74 | return function(input, start) { 75 | if (input==null) 76 | return null; 77 | start = +start; //parse to int 78 | return input.slice(start); 79 | } 80 | }); 81 | -------------------------------------------------------------------------------- /sales-client-1/js/clientesController.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | //function clientesController($scope,$http,$routeParams,$location) 4 | $app.controller('clientesController',function ($scope,$http,$routeParams,$location) { 5 | //lista de clientes 6 | $scope.rows = null; 7 | 8 | //um cliente 9 | $scope.row = null; 10 | 11 | //Pagination 12 | $scope.currentPage = 0; 13 | $scope.pageSize = 15; 14 | 15 | $scope.numberOfPages =function(){ 16 | return Math.ceil($scope.rows.length/$scope.pageSize); 17 | } 18 | 19 | $scope.loadAll = function(){ 20 | $scope.showLoader(); 21 | $http.get($scope.server("/customers")).success(function(data){ 22 | $scope.rows = data; 23 | $scope.hideLoader(); 24 | }); 25 | } 26 | 27 | $scope.loadRow = function(){ 28 | if ($routeParams.id!=null) 29 | { 30 | $scope.showLoader(); 31 | $http.get($scope.server("/customer/"+$routeParams.id)).success(function(data){ 32 | $scope.row = data; 33 | $scope.row.isUpdate = true; 34 | $scope.hideLoader(); 35 | }); 36 | } 37 | else 38 | { 39 | $scope.row = {} 40 | $scope.row.CustomerID = null; 41 | $scope.row.isUpdate = false; 42 | $scope.hideLoader(); 43 | } 44 | } 45 | 46 | $scope.save = function(){ 47 | $scope.showLoader(); 48 | $http.post($scope.server("/customer/"+$routeParams.id),$scope.row).success(function(data){ 49 | alert("Salvo com sucesso"); 50 | $scope.row.isUpdate = true; 51 | $scope.hideLoader(); 52 | }); 53 | } 54 | 55 | $scope.del = function(){ 56 | if (confirm("Deseja excluir " + $scope.row.CustomerID + "?")){ 57 | $http.delete($scope.server("/customer/"+$routeParams.id)).success(function(s){ 58 | $scope.hideLoader(); 59 | alert("Excluído com sucesso"); 60 | $location.path("/clientes"); 61 | }); 62 | } 63 | 64 | } 65 | 66 | }); -------------------------------------------------------------------------------- /sales-client-1/js/funcionariosController.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | //function funcionariosController($scope,$http,$routeParams,$location){ 4 | $app.controller('funcionariosController',function ($scope,$http,$routeParams,$location) { 5 | 6 | //lista de funcionarios 7 | $scope.rows = null; 8 | 9 | //um funcionario 10 | $scope.row = null; 11 | 12 | $scope.loadAll = function(){ 13 | $scope.showLoader(); 14 | $http.get($scope.server("/employees")).success(function(data){ 15 | $scope.rows = data; 16 | }); 17 | } 18 | 19 | $scope.loadRow = function(id){ 20 | $scope.showLoader(); 21 | $http.get($scope.server("/employee/"+id)).success(function(data){ 22 | $scope.row = data; 23 | $scope.row.isUpdate = true; 24 | }); 25 | } 26 | 27 | $scope.save = function(){ 28 | $scope.showLoader(); 29 | $http.post($scope.server("/employee/"),$scope.row).success(function(data){ 30 | alert("Salvo com sucesso"); 31 | $scope.loadAll(); 32 | }); 33 | } 34 | 35 | $scope.new = function(){ 36 | $scope.row = { 37 | EmployeeID:0, 38 | FirstName:"", 39 | LastName:"", 40 | HomePhone:"" 41 | } 42 | } 43 | 44 | 45 | 46 | }); -------------------------------------------------------------------------------- /sales-client-1/js/lib/angular-resource.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.1.4 3 | (c) 2010-2012 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(B,f,x){'use strict';f.module("ngResource",["ng"]).factory("$resource",["$http","$parse",function(y,z){function v(g,c){this.template=g+"#";this.defaults=c||{};this.urlParams={}}function w(g,c,d){function j(e,b){var p={},b=q({},c,b);k(b,function(a,b){l(a)&&(a=a());var h;a.charAt&&a.charAt(0)=="@"?(h=a.substr(1),h=z(h)(e)):h=a;p[b]=h});return p}function b(b){u(b||{},this)}var m=new v(g),d=q({},A,d);k(d,function(e,c){e.method=f.uppercase(e.method);var p=e.method=="POST"||e.method=="PUT"||e.method== 7 | "PATCH";b[c]=function(a,c,h,g){function f(){i.$resolved=!0}var n={},d,o=r,s=null;switch(arguments.length){case 4:s=g,o=h;case 3:case 2:if(l(c)){if(l(a)){o=a;s=c;break}o=c;s=h}else{n=a;d=c;o=h;break}case 1:l(a)?o=a:p?d=a:n=a;break;case 0:break;default:throw"Expected between 0-4 arguments [params, data, success, error], got "+arguments.length+" arguments.";}var i=this instanceof b?this:e.isArray?[]:new b(d),t={};k(e,function(a,b){b!="params"&&b!="isArray"&&(t[b]=u(a))});t.data=d;m.setUrlParams(t,q({}, 8 | j(d,e.params||{}),n),e.url);n=y(t);i.$resolved=!1;n.then(f,f);i.$then=n.then(function(a){var c=a.data,h=i.$then,d=i.$resolved;if(c)e.isArray?(i.length=0,k(c,function(a){i.push(new b(a))})):(u(c,i),i.$then=h,i.$resolved=d);(o||r)(i,a.headers);a.resource=i;return a},s).then;return i};b.prototype["$"+c]=function(a,e,h){var d=j(this),f=r,g;switch(arguments.length){case 3:d=a;f=e;g=h;break;case 2:case 1:l(a)?(f=a,g=e):(d=a,f=e||r);case 0:break;default:throw"Expected between 1-3 arguments [params, success, error], got "+ 9 | arguments.length+" arguments.";}b[c].call(this,d,p?this:x,f,g)}});b.bind=function(b){return w(g,q({},c,b),d)};return b}var A={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},r=f.noop,k=f.forEach,q=f.extend,u=f.copy,l=f.isFunction;v.prototype={setUrlParams:function(g,c,d){var j=this,b=d||j.template,m,e,l=j.urlParams={};k(b.split(/\W/),function(c){c&&RegExp("(^|[^\\\\]):"+c+"(\\W|$)").test(b)&&(l[c]=!0)});b=b.replace(/\\:/g, 10 | ":");c=c||{};k(j.urlParams,function(d,a){m=c.hasOwnProperty(a)?c[a]:j.defaults[a];f.isDefined(m)&&m!==null?(e=encodeURIComponent(m).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),b=b.replace(RegExp(":"+a+"(\\W|$)","g"),e+"$1")):b=b.replace(RegExp("(/?):"+a+"(\\W|$)","g"),function(a,b,c){return c.charAt(0)=="/"?c:b+c})});g.url=b.replace(/\/?#$/,"").replace(/\/*$/,"");k(c,function(b, 11 | a){if(!j.urlParams[a])g.params=g.params||{},g.params[a]=b})}};return w}])})(window,window.angular); 12 | -------------------------------------------------------------------------------- /sales-client-1/js/lib/bootswatch.js: -------------------------------------------------------------------------------- 1 | $('a[rel=tooltip]').tooltip({ 2 | 'placement': 'bottom' 3 | }); 4 | 5 | 6 | $('.navbar a, .subnav a').smoothScroll(); 7 | 8 | 9 | (function ($) { 10 | 11 | $(function(){ 12 | 13 | // fix sub nav on scroll 14 | var $win = $(window), 15 | $body = $('body'), 16 | $nav = $('.subnav'), 17 | navHeight = $('.navbar').first().height(), 18 | subnavHeight = $('.subnav').first().height(), 19 | subnavTop = $('.subnav').length && $('.subnav').offset().top - navHeight, 20 | marginTop = parseInt($body.css('margin-top'), 10); 21 | isFixed = 0; 22 | 23 | processScroll(); 24 | 25 | $win.on('scroll', processScroll); 26 | 27 | function processScroll() { 28 | var i, scrollTop = $win.scrollTop(); 29 | 30 | if (scrollTop >= subnavTop && !isFixed) { 31 | isFixed = 1; 32 | $nav.addClass('subnav-fixed'); 33 | $body.css('margin-top', marginTop + subnavHeight + 'px'); 34 | } else if (scrollTop <= subnavTop && isFixed) { 35 | isFixed = 0; 36 | $nav.removeClass('subnav-fixed'); 37 | $body.css('margin-top', marginTop + 'px'); 38 | } 39 | } 40 | 41 | }); 42 | 43 | })(window.jQuery); -------------------------------------------------------------------------------- /sales-client-1/js/lib/jquery.smooth-scroll.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Smooth Scroll - v1.4.10 - 2013-03-02 3 | * https://github.com/kswedberg/jquery-smooth-scroll 4 | * Copyright (c) 2013 Karl Swedberg 5 | * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT) 6 | */ 7 | (function(l){function t(l){return l.replace(/(:|\.)/g,"\\$1")}var e="1.4.10",o={exclude:[],excludeWithin:[],offset:0,direction:"top",scrollElement:null,scrollTarget:null,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficent:2},r=function(t){var e=[],o=!1,r=t.dir&&"left"==t.dir?"scrollLeft":"scrollTop";return this.each(function(){if(this!=document&&this!=window){var t=l(this);t[r]()>0?e.push(this):(t[r](1),o=t[r]()>0,o&&e.push(this),t[r](0))}}),e.length||this.each(function(){"BODY"===this.nodeName&&(e=[this])}),"first"===t.el&&e.length>1&&(e=[e[0]]),e};l.fn.extend({scrollable:function(l){var t=r.call(this,{dir:l});return this.pushStack(t)},firstScrollable:function(l){var t=r.call(this,{el:"first",dir:l});return this.pushStack(t)},smoothScroll:function(e){e=e||{};var o=l.extend({},l.fn.smoothScroll.defaults,e),r=l.smoothScroll.filterPath(location.pathname);return this.unbind("click.smoothscroll").bind("click.smoothscroll",function(e){var n=this,s=l(this),c=o.exclude,i=o.excludeWithin,a=0,f=0,h=!0,u={},d=location.hostname===n.hostname||!n.hostname,m=o.scrollTarget||(l.smoothScroll.filterPath(n.pathname)||r)===r,p=t(n.hash);if(o.scrollTarget||d&&m&&p){for(;h&&c.length>a;)s.is(t(c[a++]))&&(h=!1);for(;h&&i.length>f;)s.closest(i[f++]).length&&(h=!1)}else h=!1;h&&(e.preventDefault(),l.extend(u,o,{scrollTarget:o.scrollTarget||p,link:n}),l.smoothScroll(u))}),this}}),l.smoothScroll=function(t,e){var o,r,n,s,c=0,i="offset",a="scrollTop",f={},h={};"number"==typeof t?(o=l.fn.smoothScroll.defaults,n=t):(o=l.extend({},l.fn.smoothScroll.defaults,t||{}),o.scrollElement&&(i="position","static"==o.scrollElement.css("position")&&o.scrollElement.css("position","relative"))),o=l.extend({link:null},o),a="left"==o.direction?"scrollLeft":a,o.scrollElement?(r=o.scrollElement,c=r[a]()):r=l("html, body").firstScrollable(),o.beforeScroll.call(r,o),n="number"==typeof t?t:e||l(o.scrollTarget)[i]()&&l(o.scrollTarget)[i]()[o.direction]||0,f[a]=n+c+o.offset,s=o.speed,"auto"===s&&(s=f[a]||r.scrollTop(),s/=o.autoCoefficent),h={duration:s,easing:o.easing,complete:function(){o.afterScroll.call(o.link,o)}},o.step&&(h.step=o.step),r.length?r.stop().animate(f,h):o.afterScroll.call(o.link,o)},l.smoothScroll.version=e,l.smoothScroll.filterPath=function(l){return l.replace(/^\//,"").replace(/(index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},l.fn.smoothScroll.defaults=o})(jQuery); -------------------------------------------------------------------------------- /sales-client-1/view/clientes/main.html: -------------------------------------------------------------------------------- 1 |

Clientes

2 |
3 | 4 |
5 | Novo 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
IdNomeFone
{{row.CustomerID}}{{row.ContactName}}{{row.Phone}}
24 | 25 | 26 | 27 |
28 | -------------------------------------------------------------------------------- /sales-client-1/view/clientes/update.html: -------------------------------------------------------------------------------- 1 |

Cliente

2 |
3 |
4 |
5 | 6 |
7 | 8 | Campo obrigatório 9 |
10 |
11 |
12 | 13 |
14 | 15 | Campo obrigatório 16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 | 26 |
27 | 28 | 29 | Campo obrigatório 30 | Email inválido 31 | 32 |
33 |
34 |
35 | 36 |
37 | 38 | 39 | Url inválida 40 | 41 |
42 |
43 |
44 | 45 |
46 | 47 | 48 | Data inválida 49 | 50 |
51 |
52 | 53 | 54 |
55 | 56 | 57 |
58 | 59 | Voltar 60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /sales-client-1/view/funcionarios/main.html: -------------------------------------------------------------------------------- 1 |

Funcionários

2 | 3 |
4 |
5 | 8 |
9 |
10 |

{{row.LastName}}, {{row.FirstName}}

11 |
12 |
13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 | 38 |
39 | 40 |
41 |
42 |
43 |
44 | -------------------------------------------------------------------------------- /sales-client-1/view/main.html: -------------------------------------------------------------------------------- 1 |

Main Page

-------------------------------------------------------------------------------- /sales-server/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | RewriteCond %{REQUEST_FILENAME} !-f 3 | RewriteRule ^ index.php [QSA,L] -------------------------------------------------------------------------------- /sales-server/DB.php: -------------------------------------------------------------------------------- 1 | "SET NAMES utf8")); 26 | self::$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 27 | self::$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); 28 | } 29 | 30 | /** 31 | * Obtém a instancia da classe DB 32 | * @return type 33 | */ 34 | public static function getInstance() { 35 | 36 | if (empty(self::$instance)) { 37 | self::$instance = new DB(); 38 | } 39 | return self::$instance; 40 | } 41 | 42 | /** 43 | * Retorna a conexão PDO com o banco de dados 44 | * @return PDO 45 | */ 46 | public static function getConn() { 47 | self::getInstance(); 48 | return self::$connection; 49 | } 50 | 51 | /** 52 | * Prepara a SQl para ser executada posteriormente 53 | * @param String $sql 54 | * @return PDOStatement stmt 55 | */ 56 | public static function prepare($sql) { 57 | return self::getConn()->prepare($sql); 58 | } 59 | 60 | /** 61 | * Retorna o id da última consulta INSERT 62 | * @return int 63 | */ 64 | public static function lastInsertId() { 65 | return self::getConn()->lastInsertId(); 66 | } 67 | 68 | /** 69 | * Inicia uma transação 70 | * @return bool 71 | */ 72 | public static function beginTransaction(){ 73 | return self::getConn()->beginTransaction(); 74 | } 75 | 76 | /** 77 | * Comita uma transação 78 | * @return bool 79 | */ 80 | public static function commit(){ 81 | return self::getConn()->commit(); 82 | } 83 | 84 | /** 85 | * Realiza um rollback na transação 86 | * @return bool 87 | */ 88 | public static function rollBack(){ 89 | return self::getConn()->rollBack(); 90 | } 91 | 92 | /** 93 | * Formata uma data para o MySql (05/12/2012 para 2012-12-05) 94 | * @param type $date 95 | * @return type 96 | */ 97 | public static function dateToMySql($date) 98 | { 99 | return implode("-",array_reverse(explode("/",$date))); 100 | } 101 | 102 | /** 103 | * Formata uma data do MySql (2012-12-05 para 05/12/2012) 104 | * @param type $date 105 | * @return type 106 | */ 107 | public static function dateFromMySql($date) 108 | { 109 | return implode("/",array_reverse(explode("-",$date))); 110 | } 111 | 112 | } -------------------------------------------------------------------------------- /sales-server/Slim/Environment.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * Environment 37 | * 38 | * This class creates and returns a key/value array of common 39 | * environment variables for the current HTTP request. 40 | * 41 | * This is a singleton class; derived environment variables will 42 | * be common across multiple Slim applications. 43 | * 44 | * This class matches the Rack (Ruby) specification as closely 45 | * as possible. More information available below. 46 | * 47 | * @package Slim 48 | * @author Josh Lockhart 49 | * @since 1.6.0 50 | */ 51 | class Environment implements \ArrayAccess, \IteratorAggregate 52 | { 53 | /** 54 | * @var array 55 | */ 56 | protected $properties; 57 | 58 | /** 59 | * @var \Slim\Environment 60 | */ 61 | protected static $environment; 62 | 63 | /** 64 | * Get environment instance (singleton) 65 | * 66 | * This creates and/or returns an environment instance (singleton) 67 | * derived from $_SERVER variables. You may override the global server 68 | * variables by using `\Slim\Environment::mock()` instead. 69 | * 70 | * @param bool $refresh Refresh properties using global server variables? 71 | * @return \Slim\Environment 72 | */ 73 | public static function getInstance($refresh = false) 74 | { 75 | if (is_null(self::$environment) || $refresh) { 76 | self::$environment = new self(); 77 | } 78 | 79 | return self::$environment; 80 | } 81 | 82 | /** 83 | * Get mock environment instance 84 | * 85 | * @param array $userSettings 86 | * @return \Slim\Environment 87 | */ 88 | public static function mock($userSettings = array()) 89 | { 90 | self::$environment = new self(array_merge(array( 91 | 'REQUEST_METHOD' => 'GET', 92 | 'SCRIPT_NAME' => '', 93 | 'PATH_INFO' => '', 94 | 'QUERY_STRING' => '', 95 | 'SERVER_NAME' => 'localhost', 96 | 'SERVER_PORT' => 80, 97 | 'ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 98 | 'ACCEPT_LANGUAGE' => 'en-US,en;q=0.8', 99 | 'ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 100 | 'USER_AGENT' => 'Slim Framework', 101 | 'REMOTE_ADDR' => '127.0.0.1', 102 | 'slim.url_scheme' => 'http', 103 | 'slim.input' => '', 104 | 'slim.errors' => @fopen('php://stderr', 'w') 105 | ), $userSettings)); 106 | 107 | return self::$environment; 108 | } 109 | 110 | /** 111 | * Constructor (private access) 112 | * 113 | * @param array|null $settings If present, these are used instead of global server variables 114 | */ 115 | private function __construct($settings = null) 116 | { 117 | if ($settings) { 118 | $this->properties = $settings; 119 | } else { 120 | $env = array(); 121 | 122 | //The HTTP request method 123 | $env['REQUEST_METHOD'] = $_SERVER['REQUEST_METHOD']; 124 | 125 | //The IP 126 | $env['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR']; 127 | 128 | /** 129 | * Application paths 130 | * 131 | * This derives two paths: SCRIPT_NAME and PATH_INFO. The SCRIPT_NAME 132 | * is the real, physical path to the application, be it in the root 133 | * directory or a subdirectory of the public document root. The PATH_INFO is the 134 | * virtual path to the requested resource within the application context. 135 | * 136 | * With htaccess, the SCRIPT_NAME will be an absolute path (without file name); 137 | * if not using htaccess, it will also include the file name. If it is "/", 138 | * it is set to an empty string (since it cannot have a trailing slash). 139 | * 140 | * The PATH_INFO will be an absolute path with a leading slash; this will be 141 | * used for application routing. 142 | */ 143 | if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) { 144 | $env['SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME']; //Without URL rewrite 145 | } else { 146 | $env['SCRIPT_NAME'] = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']) ); //With URL rewrite 147 | } 148 | $env['PATH_INFO'] = substr_replace($_SERVER['REQUEST_URI'], '', 0, strlen($env['SCRIPT_NAME'])); 149 | if (strpos($env['PATH_INFO'], '?') !== false) { 150 | $env['PATH_INFO'] = substr_replace($env['PATH_INFO'], '', strpos($env['PATH_INFO'], '?')); //query string is not removed automatically 151 | } 152 | $env['SCRIPT_NAME'] = rtrim($env['SCRIPT_NAME'], '/'); 153 | $env['PATH_INFO'] = '/' . ltrim($env['PATH_INFO'], '/'); 154 | 155 | //The portion of the request URI following the '?' 156 | $env['QUERY_STRING'] = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; 157 | 158 | //Name of server host that is running the script 159 | $env['SERVER_NAME'] = $_SERVER['SERVER_NAME']; 160 | 161 | //Number of server port that is running the script 162 | $env['SERVER_PORT'] = $_SERVER['SERVER_PORT']; 163 | 164 | //HTTP request headers 165 | $specialHeaders = array('CONTENT_TYPE', 'CONTENT_LENGTH', 'PHP_AUTH_USER', 'PHP_AUTH_PW', 'PHP_AUTH_DIGEST', 'AUTH_TYPE'); 166 | foreach ($_SERVER as $key => $value) { 167 | $value = is_string($value) ? trim($value) : $value; 168 | if (strpos($key, 'HTTP_') === 0) { 169 | $env[substr($key, 5)] = $value; 170 | } elseif (strpos($key, 'X_') === 0 || in_array($key, $specialHeaders)) { 171 | $env[$key] = $value; 172 | } 173 | } 174 | 175 | //Is the application running under HTTPS or HTTP protocol? 176 | $env['slim.url_scheme'] = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off' ? 'http' : 'https'; 177 | 178 | //Input stream (readable one time only; not available for mutipart/form-data requests) 179 | $rawInput = @file_get_contents('php://input'); 180 | if (!$rawInput) { 181 | $rawInput = ''; 182 | } 183 | $env['slim.input'] = $rawInput; 184 | 185 | //Error stream 186 | $env['slim.errors'] = fopen('php://stderr', 'w'); 187 | 188 | $this->properties = $env; 189 | } 190 | } 191 | 192 | /** 193 | * Array Access: Offset Exists 194 | */ 195 | public function offsetExists($offset) 196 | { 197 | return isset($this->properties[$offset]); 198 | } 199 | 200 | /** 201 | * Array Access: Offset Get 202 | */ 203 | public function offsetGet($offset) 204 | { 205 | if (isset($this->properties[$offset])) { 206 | return $this->properties[$offset]; 207 | } else { 208 | return null; 209 | } 210 | } 211 | 212 | /** 213 | * Array Access: Offset Set 214 | */ 215 | public function offsetSet($offset, $value) 216 | { 217 | $this->properties[$offset] = $value; 218 | } 219 | 220 | /** 221 | * Array Access: Offset Unset 222 | */ 223 | public function offsetUnset($offset) 224 | { 225 | unset($this->properties[$offset]); 226 | } 227 | 228 | /** 229 | * IteratorAggregate 230 | * 231 | * @return \ArrayIterator 232 | */ 233 | public function getIterator() 234 | { 235 | return new \ArrayIterator($this->properties); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /sales-server/Slim/Exception/Pass.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Exception; 34 | 35 | /** 36 | * Pass Exception 37 | * 38 | * This Exception will cause the Router::dispatch method 39 | * to skip the current matching route and continue to the next 40 | * matching route. If no subsequent routes are found, a 41 | * HTTP 404 Not Found response will be sent to the client. 42 | * 43 | * @package Slim 44 | * @author Josh Lockhart 45 | * @since 1.0.0 46 | */ 47 | class Pass extends \Exception 48 | { 49 | 50 | } 51 | -------------------------------------------------------------------------------- /sales-server/Slim/Exception/Stop.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Exception; 34 | 35 | /** 36 | * Stop Exception 37 | * 38 | * This Exception is thrown when the Slim application needs to abort 39 | * processing and return control flow to the outer PHP script. 40 | * 41 | * @package Slim 42 | * @author Josh Lockhart 43 | * @since 1.0.0 44 | */ 45 | class Stop extends \Exception 46 | { 47 | 48 | } 49 | -------------------------------------------------------------------------------- /sales-server/Slim/Http/Headers.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Http; 34 | 35 | /** 36 | * HTTP Headers 37 | * 38 | * This class is an abstraction of the HTTP response headers and 39 | * provides array access to the header list while automatically 40 | * stores and retrieves headers with lowercase canonical keys regardless 41 | * of the input format. 42 | * 43 | * This class also implements the `Iterator` and `Countable` 44 | * interfaces for even more convenient usage. 45 | * 46 | * @package Slim 47 | * @author Josh Lockhart 48 | * @since 1.6.0 49 | */ 50 | class Headers implements \ArrayAccess, \Iterator, \Countable 51 | { 52 | /** 53 | * @var array HTTP headers 54 | */ 55 | protected $headers; 56 | 57 | /** 58 | * @var array Map canonical header name to original header name 59 | */ 60 | protected $map; 61 | 62 | /** 63 | * Constructor 64 | * @param array $headers 65 | */ 66 | public function __construct($headers = array()) 67 | { 68 | $this->merge($headers); 69 | } 70 | 71 | /** 72 | * Merge Headers 73 | * @param array $headers 74 | */ 75 | public function merge($headers) 76 | { 77 | foreach ($headers as $name => $value) { 78 | $this[$name] = $value; 79 | } 80 | } 81 | 82 | /** 83 | * Transform header name into canonical form 84 | * @param string $name 85 | * @return string 86 | */ 87 | protected function canonical($name) 88 | { 89 | return strtolower(trim($name)); 90 | } 91 | 92 | /** 93 | * Array Access: Offset Exists 94 | */ 95 | public function offsetExists($offset) 96 | { 97 | return isset($this->headers[$this->canonical($offset)]); 98 | } 99 | 100 | /** 101 | * Array Access: Offset Get 102 | */ 103 | public function offsetGet($offset) 104 | { 105 | $canonical = $this->canonical($offset); 106 | if (isset($this->headers[$canonical])) { 107 | return $this->headers[$canonical]; 108 | } else { 109 | return null; 110 | } 111 | } 112 | 113 | /** 114 | * Array Access: Offset Set 115 | */ 116 | public function offsetSet($offset, $value) 117 | { 118 | $canonical = $this->canonical($offset); 119 | $this->headers[$canonical] = $value; 120 | $this->map[$canonical] = $offset; 121 | } 122 | 123 | /** 124 | * Array Access: Offset Unset 125 | */ 126 | public function offsetUnset($offset) 127 | { 128 | $canonical = $this->canonical($offset); 129 | unset($this->headers[$canonical], $this->map[$canonical]); 130 | } 131 | 132 | /** 133 | * Countable: Count 134 | */ 135 | public function count() 136 | { 137 | return count($this->headers); 138 | } 139 | 140 | /** 141 | * Iterator: Rewind 142 | */ 143 | public function rewind() 144 | { 145 | reset($this->headers); 146 | } 147 | 148 | /** 149 | * Iterator: Current 150 | */ 151 | public function current() 152 | { 153 | return current($this->headers); 154 | } 155 | 156 | /** 157 | * Iterator: Key 158 | */ 159 | public function key() 160 | { 161 | $key = key($this->headers); 162 | 163 | return $this->map[$key]; 164 | } 165 | 166 | /** 167 | * Iterator: Next 168 | */ 169 | public function next() 170 | { 171 | return next($this->headers); 172 | } 173 | 174 | /** 175 | * Iterator: Valid 176 | */ 177 | public function valid() 178 | { 179 | return current($this->headers) !== false; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /sales-server/Slim/Http/Response.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Http; 34 | 35 | /** 36 | * Response 37 | * 38 | * This is a simple abstraction over top an HTTP response. This 39 | * provides methods to set the HTTP status, the HTTP headers, 40 | * and the HTTP body. 41 | * 42 | * @package Slim 43 | * @author Josh Lockhart 44 | * @since 1.0.0 45 | */ 46 | class Response implements \ArrayAccess, \Countable, \IteratorAggregate 47 | { 48 | /** 49 | * @var int HTTP status code 50 | */ 51 | protected $status; 52 | 53 | /** 54 | * @var \Slim\Http\Headers List of HTTP response headers 55 | */ 56 | protected $header; 57 | 58 | /** 59 | * @var string HTTP response body 60 | */ 61 | protected $body; 62 | 63 | /** 64 | * @var int Length of HTTP response body 65 | */ 66 | protected $length; 67 | 68 | /** 69 | * @var array HTTP response codes and messages 70 | */ 71 | protected static $messages = array( 72 | //Informational 1xx 73 | 100 => '100 Continue', 74 | 101 => '101 Switching Protocols', 75 | //Successful 2xx 76 | 200 => '200 OK', 77 | 201 => '201 Created', 78 | 202 => '202 Accepted', 79 | 203 => '203 Non-Authoritative Information', 80 | 204 => '204 No Content', 81 | 205 => '205 Reset Content', 82 | 206 => '206 Partial Content', 83 | //Redirection 3xx 84 | 300 => '300 Multiple Choices', 85 | 301 => '301 Moved Permanently', 86 | 302 => '302 Found', 87 | 303 => '303 See Other', 88 | 304 => '304 Not Modified', 89 | 305 => '305 Use Proxy', 90 | 306 => '306 (Unused)', 91 | 307 => '307 Temporary Redirect', 92 | //Client Error 4xx 93 | 400 => '400 Bad Request', 94 | 401 => '401 Unauthorized', 95 | 402 => '402 Payment Required', 96 | 403 => '403 Forbidden', 97 | 404 => '404 Not Found', 98 | 405 => '405 Method Not Allowed', 99 | 406 => '406 Not Acceptable', 100 | 407 => '407 Proxy Authentication Required', 101 | 408 => '408 Request Timeout', 102 | 409 => '409 Conflict', 103 | 410 => '410 Gone', 104 | 411 => '411 Length Required', 105 | 412 => '412 Precondition Failed', 106 | 413 => '413 Request Entity Too Large', 107 | 414 => '414 Request-URI Too Long', 108 | 415 => '415 Unsupported Media Type', 109 | 416 => '416 Requested Range Not Satisfiable', 110 | 417 => '417 Expectation Failed', 111 | 422 => '422 Unprocessable Entity', 112 | 423 => '423 Locked', 113 | //Server Error 5xx 114 | 500 => '500 Internal Server Error', 115 | 501 => '501 Not Implemented', 116 | 502 => '502 Bad Gateway', 117 | 503 => '503 Service Unavailable', 118 | 504 => '504 Gateway Timeout', 119 | 505 => '505 HTTP Version Not Supported' 120 | ); 121 | 122 | /** 123 | * Constructor 124 | * @param string $body The HTTP response body 125 | * @param int $status The HTTP response status 126 | * @param \Slim\Http\Headers|array $header The HTTP response headers 127 | */ 128 | public function __construct($body = '', $status = 200, $header = array()) 129 | { 130 | $this->status = (int) $status; 131 | $headers = array(); 132 | foreach ($header as $key => $value) { 133 | $headers[$key] = $value; 134 | } 135 | $this->header = new Headers(array_merge(array('Content-Type' => 'text/html'), $headers)); 136 | $this->body = ''; 137 | $this->write($body); 138 | } 139 | 140 | /** 141 | * Get and set status 142 | * @param int|null $status 143 | * @return int 144 | */ 145 | public function status($status = null) 146 | { 147 | if (!is_null($status)) { 148 | $this->status = (int) $status; 149 | } 150 | 151 | return $this->status; 152 | } 153 | 154 | /** 155 | * Get and set header 156 | * @param string $name Header name 157 | * @param string|null $value Header value 158 | * @return string Header value 159 | */ 160 | public function header($name, $value = null) 161 | { 162 | if (!is_null($value)) { 163 | $this[$name] = $value; 164 | } 165 | 166 | return $this[$name]; 167 | } 168 | 169 | /** 170 | * Get headers 171 | * @return \Slim\Http\Headers 172 | */ 173 | public function headers() 174 | { 175 | return $this->header; 176 | } 177 | 178 | /** 179 | * Get and set body 180 | * @param string|null $body Content of HTTP response body 181 | * @return string 182 | */ 183 | public function body($body = null) 184 | { 185 | if (!is_null($body)) { 186 | $this->write($body, true); 187 | } 188 | 189 | return $this->body; 190 | } 191 | 192 | /** 193 | * Get and set length 194 | * @param int|null $length 195 | * @return int 196 | */ 197 | public function length($length = null) 198 | { 199 | if (!is_null($length)) { 200 | $this->length = (int) $length; 201 | } 202 | 203 | return $this->length; 204 | } 205 | 206 | /** 207 | * Append HTTP response body 208 | * @param string $body Content to append to the current HTTP response body 209 | * @param bool $replace Overwrite existing response body? 210 | * @return string The updated HTTP response body 211 | */ 212 | public function write($body, $replace = false) 213 | { 214 | if ($replace) { 215 | $this->body = $body; 216 | } else { 217 | $this->body .= (string) $body; 218 | } 219 | $this->length = strlen($this->body); 220 | 221 | return $this->body; 222 | } 223 | 224 | /** 225 | * Finalize 226 | * 227 | * This prepares this response and returns an array 228 | * of [status, headers, body]. This array is passed to outer middleware 229 | * if available or directly to the Slim run method. 230 | * 231 | * @return array[int status, array headers, string body] 232 | */ 233 | public function finalize() 234 | { 235 | if (in_array($this->status, array(204, 304))) { 236 | unset($this['Content-Type'], $this['Content-Length']); 237 | 238 | return array($this->status, $this->header, ''); 239 | } else { 240 | return array($this->status, $this->header, $this->body); 241 | } 242 | } 243 | 244 | /** 245 | * Set cookie 246 | * 247 | * Instead of using PHP's `setcookie()` function, Slim manually constructs the HTTP `Set-Cookie` 248 | * header on its own and delegates this responsibility to the `Slim_Http_Util` class. This 249 | * response's header is passed by reference to the utility class and is directly modified. By not 250 | * relying on PHP's native implementation, Slim allows middleware the opportunity to massage or 251 | * analyze the raw header before the response is ultimately delivered to the HTTP client. 252 | * 253 | * @param string $name The name of the cookie 254 | * @param string|array $value If string, the value of cookie; if array, properties for 255 | * cookie including: value, expire, path, domain, secure, httponly 256 | */ 257 | public function setCookie($name, $value) 258 | { 259 | Util::setCookieHeader($this->header, $name, $value); 260 | } 261 | 262 | /** 263 | * Delete cookie 264 | * 265 | * Instead of using PHP's `setcookie()` function, Slim manually constructs the HTTP `Set-Cookie` 266 | * header on its own and delegates this responsibility to the `Slim_Http_Util` class. This 267 | * response's header is passed by reference to the utility class and is directly modified. By not 268 | * relying on PHP's native implementation, Slim allows middleware the opportunity to massage or 269 | * analyze the raw header before the response is ultimately delivered to the HTTP client. 270 | * 271 | * This method will set a cookie with the given name that has an expiration time in the past; this will 272 | * prompt the HTTP client to invalidate and remove the client-side cookie. Optionally, you may 273 | * also pass a key/value array as the second argument. If the "domain" key is present in this 274 | * array, only the Cookie with the given name AND domain will be removed. The invalidating cookie 275 | * sent with this response will adopt all properties of the second argument. 276 | * 277 | * @param string $name The name of the cookie 278 | * @param array $value Properties for cookie including: value, expire, path, domain, secure, httponly 279 | */ 280 | public function deleteCookie($name, $value = array()) 281 | { 282 | Util::deleteCookieHeader($this->header, $name, $value); 283 | } 284 | 285 | /** 286 | * Redirect 287 | * 288 | * This method prepares this response to return an HTTP Redirect response 289 | * to the HTTP client. 290 | * 291 | * @param string $url The redirect destination 292 | * @param int $status The redirect HTTP status code 293 | */ 294 | public function redirect ($url, $status = 302) 295 | { 296 | $this->status = $status; 297 | $this['Location'] = $url; 298 | } 299 | 300 | /** 301 | * Helpers: Empty? 302 | * @return bool 303 | */ 304 | public function isEmpty() 305 | { 306 | return in_array($this->status, array(201, 204, 304)); 307 | } 308 | 309 | /** 310 | * Helpers: Informational? 311 | * @return bool 312 | */ 313 | public function isInformational() 314 | { 315 | return $this->status >= 100 && $this->status < 200; 316 | } 317 | 318 | /** 319 | * Helpers: OK? 320 | * @return bool 321 | */ 322 | public function isOk() 323 | { 324 | return $this->status === 200; 325 | } 326 | 327 | /** 328 | * Helpers: Successful? 329 | * @return bool 330 | */ 331 | public function isSuccessful() 332 | { 333 | return $this->status >= 200 && $this->status < 300; 334 | } 335 | 336 | /** 337 | * Helpers: Redirect? 338 | * @return bool 339 | */ 340 | public function isRedirect() 341 | { 342 | return in_array($this->status, array(301, 302, 303, 307)); 343 | } 344 | 345 | /** 346 | * Helpers: Redirection? 347 | * @return bool 348 | */ 349 | public function isRedirection() 350 | { 351 | return $this->status >= 300 && $this->status < 400; 352 | } 353 | 354 | /** 355 | * Helpers: Forbidden? 356 | * @return bool 357 | */ 358 | public function isForbidden() 359 | { 360 | return $this->status === 403; 361 | } 362 | 363 | /** 364 | * Helpers: Not Found? 365 | * @return bool 366 | */ 367 | public function isNotFound() 368 | { 369 | return $this->status === 404; 370 | } 371 | 372 | /** 373 | * Helpers: Client error? 374 | * @return bool 375 | */ 376 | public function isClientError() 377 | { 378 | return $this->status >= 400 && $this->status < 500; 379 | } 380 | 381 | /** 382 | * Helpers: Server Error? 383 | * @return bool 384 | */ 385 | public function isServerError() 386 | { 387 | return $this->status >= 500 && $this->status < 600; 388 | } 389 | 390 | /** 391 | * Array Access: Offset Exists 392 | */ 393 | public function offsetExists( $offset ) 394 | { 395 | return isset($this->header[$offset]); 396 | } 397 | 398 | /** 399 | * Array Access: Offset Get 400 | */ 401 | public function offsetGet( $offset ) 402 | { 403 | if (isset($this->header[$offset])) { 404 | return $this->header[$offset]; 405 | } else { 406 | return null; 407 | } 408 | } 409 | 410 | /** 411 | * Array Access: Offset Set 412 | */ 413 | public function offsetSet($offset, $value) 414 | { 415 | $this->header[$offset] = $value; 416 | } 417 | 418 | /** 419 | * Array Access: Offset Unset 420 | */ 421 | public function offsetUnset($offset) 422 | { 423 | unset($this->header[$offset]); 424 | } 425 | 426 | /** 427 | * Countable: Count 428 | */ 429 | public function count() 430 | { 431 | return count($this->header); 432 | } 433 | 434 | /** 435 | * Get Iterator 436 | * 437 | * This returns the contained `\Slim\Http\Headers` instance which 438 | * is itself iterable. 439 | * 440 | * @return \Slim\Http\Headers 441 | */ 442 | public function getIterator() 443 | { 444 | return $this->header; 445 | } 446 | 447 | /** 448 | * Get message for HTTP status code 449 | * @return string|null 450 | */ 451 | public static function getMessageForCode($status) 452 | { 453 | if (isset(self::$messages[$status])) { 454 | return self::$messages[$status]; 455 | } else { 456 | return null; 457 | } 458 | } 459 | } 460 | -------------------------------------------------------------------------------- /sales-server/Slim/Http/Util.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Http; 34 | 35 | /** 36 | * Slim HTTP Utilities 37 | * 38 | * This class provides useful methods for handling HTTP requests. 39 | * 40 | * @package Slim 41 | * @author Josh Lockhart 42 | * @since 1.0.0 43 | */ 44 | class Util 45 | { 46 | /** 47 | * Strip slashes from string or array 48 | * 49 | * This method strips slashes from its input. By default, this method will only 50 | * strip slashes from its input if magic quotes are enabled. Otherwise, you may 51 | * override the magic quotes setting with either TRUE or FALSE as the send argument 52 | * to force this method to strip or not strip slashes from its input. 53 | * 54 | * @var array|string $rawData 55 | * @return array|string 56 | */ 57 | public static function stripSlashesIfMagicQuotes($rawData, $overrideStripSlashes = null) 58 | { 59 | $strip = is_null($overrideStripSlashes) ? get_magic_quotes_gpc() : $overrideStripSlashes; 60 | if ($strip) { 61 | return self::_stripSlashes($rawData); 62 | } else { 63 | return $rawData; 64 | } 65 | } 66 | 67 | /** 68 | * Strip slashes from string or array 69 | * @param array|string $rawData 70 | * @return array|string 71 | */ 72 | protected static function _stripSlashes($rawData) 73 | { 74 | return is_array($rawData) ? array_map(array('self', '_stripSlashes'), $rawData) : stripslashes($rawData); 75 | } 76 | 77 | /** 78 | * Encrypt data 79 | * 80 | * This method will encrypt data using a given key, vector, and cipher. 81 | * By default, this will encrypt data using the RIJNDAEL/AES 256 bit cipher. You 82 | * may override the default cipher and cipher mode by passing your own desired 83 | * cipher and cipher mode as the final key-value array argument. 84 | * 85 | * @param string $data The unencrypted data 86 | * @param string $key The encryption key 87 | * @param string $iv The encryption initialization vector 88 | * @param array $settings Optional key-value array with custom algorithm and mode 89 | * @return string 90 | */ 91 | public static function encrypt($data, $key, $iv, $settings = array()) 92 | { 93 | if ($data === '' || !extension_loaded('mcrypt')) { 94 | return $data; 95 | } 96 | 97 | //Merge settings with defaults 98 | $settings = array_merge(array( 99 | 'algorithm' => MCRYPT_RIJNDAEL_256, 100 | 'mode' => MCRYPT_MODE_CBC 101 | ), $settings); 102 | 103 | //Get module 104 | $module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], ''); 105 | 106 | //Validate IV 107 | $ivSize = mcrypt_enc_get_iv_size($module); 108 | if (strlen($iv) > $ivSize) { 109 | $iv = substr($iv, 0, $ivSize); 110 | } 111 | 112 | //Validate key 113 | $keySize = mcrypt_enc_get_key_size($module); 114 | if (strlen($key) > $keySize) { 115 | $key = substr($key, 0, $keySize); 116 | } 117 | 118 | //Encrypt value 119 | mcrypt_generic_init($module, $key, $iv); 120 | $res = @mcrypt_generic($module, $data); 121 | mcrypt_generic_deinit($module); 122 | 123 | return $res; 124 | } 125 | 126 | /** 127 | * Decrypt data 128 | * 129 | * This method will decrypt data using a given key, vector, and cipher. 130 | * By default, this will decrypt data using the RIJNDAEL/AES 256 bit cipher. You 131 | * may override the default cipher and cipher mode by passing your own desired 132 | * cipher and cipher mode as the final key-value array argument. 133 | * 134 | * @param string $data The encrypted data 135 | * @param string $key The encryption key 136 | * @param string $iv The encryption initialization vector 137 | * @param array $settings Optional key-value array with custom algorithm and mode 138 | * @return string 139 | */ 140 | public static function decrypt($data, $key, $iv, $settings = array()) 141 | { 142 | if ($data === '' || !extension_loaded('mcrypt')) { 143 | return $data; 144 | } 145 | 146 | //Merge settings with defaults 147 | $settings = array_merge(array( 148 | 'algorithm' => MCRYPT_RIJNDAEL_256, 149 | 'mode' => MCRYPT_MODE_CBC 150 | ), $settings); 151 | 152 | //Get module 153 | $module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], ''); 154 | 155 | //Validate IV 156 | $ivSize = mcrypt_enc_get_iv_size($module); 157 | if (strlen($iv) > $ivSize) { 158 | $iv = substr($iv, 0, $ivSize); 159 | } 160 | 161 | //Validate key 162 | $keySize = mcrypt_enc_get_key_size($module); 163 | if (strlen($key) > $keySize) { 164 | $key = substr($key, 0, $keySize); 165 | } 166 | 167 | //Decrypt value 168 | mcrypt_generic_init($module, $key, $iv); 169 | $decryptedData = @mdecrypt_generic($module, $data); 170 | $res = str_replace("\x0", '', $decryptedData); 171 | mcrypt_generic_deinit($module); 172 | 173 | return $res; 174 | } 175 | 176 | /** 177 | * Encode secure cookie value 178 | * 179 | * This method will create the secure value of an HTTP cookie. The 180 | * cookie value is encrypted and hashed so that its value is 181 | * secure and checked for integrity when read in subsequent requests. 182 | * 183 | * @param string $value The unsecure HTTP cookie value 184 | * @param int $expires The UNIX timestamp at which this cookie will expire 185 | * @param string $secret The secret key used to hash the cookie value 186 | * @param int $algorithm The algorithm to use for encryption 187 | * @param int $mode The algorithm mode to use for encryption 188 | * @param string 189 | */ 190 | public static function encodeSecureCookie($value, $expires, $secret, $algorithm, $mode) 191 | { 192 | $key = hash_hmac('sha1', $expires, $secret); 193 | $iv = self::get_iv($expires, $secret); 194 | $secureString = base64_encode(self::encrypt($value, $key, $iv, array( 195 | 'algorithm' => $algorithm, 196 | 'mode' => $mode 197 | ))); 198 | $verificationString = hash_hmac('sha1', $expires . $value, $key); 199 | 200 | return implode('|', array($expires, $secureString, $verificationString)); 201 | } 202 | 203 | /** 204 | * Decode secure cookie value 205 | * 206 | * This method will decode the secure value of an HTTP cookie. The 207 | * cookie value is encrypted and hashed so that its value is 208 | * secure and checked for integrity when read in subsequent requests. 209 | * 210 | * @param string $value The secure HTTP cookie value 211 | * @param int $expires The UNIX timestamp at which this cookie will expire 212 | * @param string $secret The secret key used to hash the cookie value 213 | * @param int $algorithm The algorithm to use for encryption 214 | * @param int $mode The algorithm mode to use for encryption 215 | * @param string 216 | */ 217 | public static function decodeSecureCookie($value, $secret, $algorithm, $mode) 218 | { 219 | if ($value) { 220 | $value = explode('|', $value); 221 | if (count($value) === 3 && ((int) $value[0] === 0 || (int) $value[0] > time())) { 222 | $key = hash_hmac('sha1', $value[0], $secret); 223 | $iv = self::get_iv($value[0], $secret); 224 | $data = self::decrypt(base64_decode($value[1]), $key, $iv, array( 225 | 'algorithm' => $algorithm, 226 | 'mode' => $mode 227 | )); 228 | $verificationString = hash_hmac('sha1', $value[0] . $data, $key); 229 | if ($verificationString === $value[2]) { 230 | return $data; 231 | } 232 | } 233 | } 234 | 235 | return false; 236 | } 237 | 238 | /** 239 | * Set HTTP cookie header 240 | * 241 | * This method will construct and set the HTTP `Set-Cookie` header. Slim 242 | * uses this method instead of PHP's native `setcookie` method. This allows 243 | * more control of the HTTP header irrespective of the native implementation's 244 | * dependency on PHP versions. 245 | * 246 | * This method accepts the Slim_Http_Headers object by reference as its 247 | * first argument; this method directly modifies this object instead of 248 | * returning a value. 249 | * 250 | * @param array $header 251 | * @param string $name 252 | * @param string $value 253 | */ 254 | public static function setCookieHeader(&$header, $name, $value) 255 | { 256 | //Build cookie header 257 | if (is_array($value)) { 258 | $domain = ''; 259 | $path = ''; 260 | $expires = ''; 261 | $secure = ''; 262 | $httponly = ''; 263 | if (isset($value['domain']) && $value['domain']) { 264 | $domain = '; domain=' . $value['domain']; 265 | } 266 | if (isset($value['path']) && $value['path']) { 267 | $path = '; path=' . $value['path']; 268 | } 269 | if (isset($value['expires'])) { 270 | if (is_string($value['expires'])) { 271 | $timestamp = strtotime($value['expires']); 272 | } else { 273 | $timestamp = (int) $value['expires']; 274 | } 275 | if ($timestamp !== 0) { 276 | $expires = '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp); 277 | } 278 | } 279 | if (isset($value['secure']) && $value['secure']) { 280 | $secure = '; secure'; 281 | } 282 | if (isset($value['httponly']) && $value['httponly']) { 283 | $httponly = '; HttpOnly'; 284 | } 285 | $cookie = sprintf('%s=%s%s', urlencode($name), urlencode((string) $value['value']), $domain . $path . $expires . $secure . $httponly); 286 | } else { 287 | $cookie = sprintf('%s=%s', urlencode($name), urlencode((string) $value)); 288 | } 289 | 290 | //Set cookie header 291 | if (!isset($header['Set-Cookie']) || $header['Set-Cookie'] === '') { 292 | $header['Set-Cookie'] = $cookie; 293 | } else { 294 | $header['Set-Cookie'] = implode("\n", array($header['Set-Cookie'], $cookie)); 295 | } 296 | } 297 | 298 | /** 299 | * Delete HTTP cookie header 300 | * 301 | * This method will construct and set the HTTP `Set-Cookie` header to invalidate 302 | * a client-side HTTP cookie. If a cookie with the same name (and, optionally, domain) 303 | * is already set in the HTTP response, it will also be removed. Slim uses this method 304 | * instead of PHP's native `setcookie` method. This allows more control of the HTTP header 305 | * irrespective of PHP's native implementation's dependency on PHP versions. 306 | * 307 | * This method accepts the Slim_Http_Headers object by reference as its 308 | * first argument; this method directly modifies this object instead of 309 | * returning a value. 310 | * 311 | * @param array $header 312 | * @param string $name 313 | * @param string $value 314 | */ 315 | public static function deleteCookieHeader(&$header, $name, $value = array()) 316 | { 317 | //Remove affected cookies from current response header 318 | $cookiesOld = array(); 319 | $cookiesNew = array(); 320 | if (isset($header['Set-Cookie'])) { 321 | $cookiesOld = explode("\n", $header['Set-Cookie']); 322 | } 323 | foreach ($cookiesOld as $c) { 324 | if (isset($value['domain']) && $value['domain']) { 325 | $regex = sprintf('@%s=.*domain=%s@', urlencode($name), preg_quote($value['domain'])); 326 | } else { 327 | $regex = sprintf('@%s=@', urlencode($name)); 328 | } 329 | if (preg_match($regex, $c) === 0) { 330 | $cookiesNew[] = $c; 331 | } 332 | } 333 | if ($cookiesNew) { 334 | $header['Set-Cookie'] = implode("\n", $cookiesNew); 335 | } else { 336 | unset($header['Set-Cookie']); 337 | } 338 | 339 | //Set invalidating cookie to clear client-side cookie 340 | self::setCookieHeader($header, $name, array_merge(array('value' => '', 'path' => null, 'domain' => null, 'expires' => time() - 100), $value)); 341 | } 342 | 343 | /** 344 | * Parse cookie header 345 | * 346 | * This method will parse the HTTP requst's `Cookie` header 347 | * and extract cookies into an associative array. 348 | * 349 | * @param string 350 | * @return array 351 | */ 352 | public static function parseCookieHeader($header) 353 | { 354 | $cookies = array(); 355 | $header = rtrim($header, "\r\n"); 356 | $headerPieces = preg_split('@\s*[;,]\s*@', $header); 357 | foreach ($headerPieces as $c) { 358 | $cParts = explode('=', $c); 359 | if (count($cParts) === 2) { 360 | $key = urldecode($cParts[0]); 361 | $value = urldecode($cParts[1]); 362 | if (!isset($cookies[$key])) { 363 | $cookies[$key] = $value; 364 | } 365 | } 366 | } 367 | 368 | return $cookies; 369 | } 370 | 371 | /** 372 | * Generate a random IV 373 | * 374 | * This method will generate a non-predictable IV for use with 375 | * the cookie encryption 376 | * 377 | * @param int $expires The UNIX timestamp at which this cookie will expire 378 | * @param string $secret The secret key used to hash the cookie value 379 | * @return binary string with length 40 380 | */ 381 | private static function get_iv($expires, $secret) 382 | { 383 | $data1 = hash_hmac('sha1', 'a'.$expires.'b', $secret); 384 | $data2 = hash_hmac('sha1', 'z'.$expires.'y', $secret); 385 | 386 | return pack("h*", $data1.$data2); 387 | } 388 | 389 | } 390 | -------------------------------------------------------------------------------- /sales-server/Slim/Log.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * Log 37 | * 38 | * This is the primary logger for a Slim application. You may provide 39 | * a Log Writer in conjunction with this Log to write to various output 40 | * destinations (e.g. a file). This class provides this interface: 41 | * 42 | * debug( mixed $object ) 43 | * info( mixed $object ) 44 | * warn( mixed $object ) 45 | * error( mixed $object ) 46 | * fatal( mixed $object ) 47 | * 48 | * This class assumes only that your Log Writer has a public `write()` method 49 | * that accepts any object as its one and only argument. The Log Writer 50 | * class may write or send its argument anywhere: a file, STDERR, 51 | * a remote web API, etc. The possibilities are endless. 52 | * 53 | * @package Slim 54 | * @author Josh Lockhart 55 | * @since 1.0.0 56 | */ 57 | class Log 58 | { 59 | const FATAL = 0; 60 | const ERROR = 1; 61 | const WARN = 2; 62 | const INFO = 3; 63 | const DEBUG = 4; 64 | 65 | /** 66 | * @var array 67 | */ 68 | protected static $levels = array( 69 | self::FATAL => 'FATAL', 70 | self::ERROR => 'ERROR', 71 | self::WARN => 'WARN', 72 | self::INFO => 'INFO', 73 | self::DEBUG => 'DEBUG' 74 | ); 75 | 76 | /** 77 | * @var mixed 78 | */ 79 | protected $writer; 80 | 81 | /** 82 | * @var bool 83 | */ 84 | protected $enabled; 85 | 86 | /** 87 | * @var int 88 | */ 89 | protected $level; 90 | 91 | /** 92 | * Constructor 93 | * @param mixed $writer 94 | */ 95 | public function __construct($writer) 96 | { 97 | $this->writer = $writer; 98 | $this->enabled = true; 99 | $this->level = self::DEBUG; 100 | } 101 | 102 | /** 103 | * Is logging enabled? 104 | * @return bool 105 | */ 106 | public function getEnabled() 107 | { 108 | return $this->enabled; 109 | } 110 | 111 | /** 112 | * Enable or disable logging 113 | * @param bool $enabled 114 | */ 115 | public function setEnabled($enabled) 116 | { 117 | if ($enabled) { 118 | $this->enabled = true; 119 | } else { 120 | $this->enabled = false; 121 | } 122 | } 123 | 124 | /** 125 | * Set level 126 | * @param int $level 127 | * @throws \InvalidArgumentException If invalid log level specified 128 | */ 129 | public function setLevel($level) 130 | { 131 | if (!isset(self::$levels[$level])) { 132 | throw new \InvalidArgumentException('Invalid log level'); 133 | } 134 | $this->level = $level; 135 | } 136 | 137 | /** 138 | * Get level 139 | * @return int 140 | */ 141 | public function getLevel() 142 | { 143 | return $this->level; 144 | } 145 | 146 | /** 147 | * Set writer 148 | * @param mixed $writer 149 | */ 150 | public function setWriter($writer) 151 | { 152 | $this->writer = $writer; 153 | } 154 | 155 | /** 156 | * Get writer 157 | * @return mixed 158 | */ 159 | public function getWriter() 160 | { 161 | return $this->writer; 162 | } 163 | 164 | /** 165 | * Is logging enabled? 166 | * @return bool 167 | */ 168 | public function isEnabled() 169 | { 170 | return $this->enabled; 171 | } 172 | 173 | /** 174 | * Log debug message 175 | * @param mixed $object 176 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled 177 | */ 178 | public function debug($object) 179 | { 180 | return $this->write($object, self::DEBUG); 181 | } 182 | 183 | /** 184 | * Log info message 185 | * @param mixed $object 186 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled 187 | */ 188 | public function info($object) 189 | { 190 | return $this->write($object, self::INFO); 191 | } 192 | 193 | /** 194 | * Log warn message 195 | * @param mixed $object 196 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled 197 | */ 198 | public function warn($object) 199 | { 200 | return $this->write($object, self::WARN); 201 | } 202 | 203 | /** 204 | * Log error message 205 | * @param mixed $object 206 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled 207 | */ 208 | public function error($object) 209 | { 210 | return $this->write($object, self::ERROR); 211 | } 212 | 213 | /** 214 | * Log fatal message 215 | * @param mixed $object 216 | * @return mixed|false What the Logger returns, or false if Logger not set or not enabled 217 | */ 218 | public function fatal($object) 219 | { 220 | return $this->write($object, self::FATAL); 221 | } 222 | 223 | /** 224 | * Log message 225 | * @param mixed The object to log 226 | * @param int The message level 227 | * @return int|false 228 | */ 229 | protected function write($object, $level) 230 | { 231 | if ($this->enabled && $this->writer && $level <= $this->level) { 232 | return $this->writer->write($object, $level); 233 | } else { 234 | return false; 235 | } 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /sales-server/Slim/LogWriter.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * Log Writer 37 | * 38 | * This class is used by Slim_Log to write log messages to a valid, writable 39 | * resource handle (e.g. a file or STDERR). 40 | * 41 | * @package Slim 42 | * @author Josh Lockhart 43 | * @since 1.6.0 44 | */ 45 | class LogWriter 46 | { 47 | /** 48 | * @var resource 49 | */ 50 | protected $resource; 51 | 52 | /** 53 | * Constructor 54 | * @param resource $resource 55 | * @throws \InvalidArgumentException If invalid resource 56 | */ 57 | public function __construct($resource) 58 | { 59 | if (!is_resource($resource)) { 60 | throw new \InvalidArgumentException('Cannot create LogWriter. Invalid resource handle.'); 61 | } 62 | $this->resource = $resource; 63 | } 64 | 65 | /** 66 | * Write message 67 | * @param mixed $message 68 | * @param int $level 69 | * @return int|false 70 | */ 71 | public function write($message, $level = null) 72 | { 73 | return fwrite($this->resource, (string) $message . PHP_EOL); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sales-server/Slim/Middleware.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * Middleware 37 | * 38 | * @package Slim 39 | * @author Josh Lockhart 40 | * @since 1.6.0 41 | */ 42 | abstract class Middleware 43 | { 44 | /** 45 | * @var \Slim Reference to the primary application instance 46 | */ 47 | protected $app; 48 | 49 | /** 50 | * @var mixed Reference to the next downstream middleware 51 | */ 52 | protected $next; 53 | 54 | /** 55 | * Set application 56 | * 57 | * This method injects the primary Slim application instance into 58 | * this middleware. 59 | * 60 | * @param \Slim $application 61 | */ 62 | final public function setApplication($application) 63 | { 64 | $this->app = $application; 65 | } 66 | 67 | /** 68 | * Get application 69 | * 70 | * This method retrieves the application previously injected 71 | * into this middleware. 72 | * 73 | * @return \Slim 74 | */ 75 | final public function getApplication() 76 | { 77 | return $this->app; 78 | } 79 | 80 | /** 81 | * Set next middleware 82 | * 83 | * This method injects the next downstream middleware into 84 | * this middleware so that it may optionally be called 85 | * when appropriate. 86 | * 87 | * @param \Slim|\Slim\Middleware 88 | */ 89 | final public function setNextMiddleware($nextMiddleware) 90 | { 91 | $this->next = $nextMiddleware; 92 | } 93 | 94 | /** 95 | * Get next middleware 96 | * 97 | * This method retrieves the next downstream middleware 98 | * previously injected into this middleware. 99 | * 100 | * @return \Slim|\Slim\Middleware 101 | */ 102 | final public function getNextMiddleware() 103 | { 104 | return $this->next; 105 | } 106 | 107 | /** 108 | * Call 109 | * 110 | * Perform actions specific to this middleware and optionally 111 | * call the next downstream middleware. 112 | */ 113 | abstract public function call(); 114 | } 115 | -------------------------------------------------------------------------------- /sales-server/Slim/Middleware/ContentTypes.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Middleware; 34 | 35 | /** 36 | * Content Types 37 | * 38 | * This is middleware for a Slim application that intercepts 39 | * the HTTP request body and parses it into the appropriate 40 | * PHP data structure if possible; else it returns the HTTP 41 | * request body unchanged. This is particularly useful 42 | * for preparing the HTTP request body for an XML or JSON API. 43 | * 44 | * @package Slim 45 | * @author Josh Lockhart 46 | * @since 1.6.0 47 | */ 48 | class ContentTypes extends \Slim\Middleware 49 | { 50 | /** 51 | * @var array 52 | */ 53 | protected $contentTypes; 54 | 55 | /** 56 | * Constructor 57 | * @param array $settings 58 | */ 59 | public function __construct($settings = array()) 60 | { 61 | $this->contentTypes = array_merge(array( 62 | 'application/json' => array($this, 'parseJson'), 63 | 'application/xml' => array($this, 'parseXml'), 64 | 'text/xml' => array($this, 'parseXml'), 65 | 'text/csv' => array($this, 'parseCsv') 66 | ), $settings); 67 | } 68 | 69 | /** 70 | * Call 71 | */ 72 | public function call() 73 | { 74 | $mediaType = $this->app->request()->getMediaType(); 75 | if ($mediaType) { 76 | $env = $this->app->environment(); 77 | $env['slim.input_original'] = $env['slim.input']; 78 | $env['slim.input'] = $this->parse($env['slim.input'], $mediaType); 79 | } 80 | $this->next->call(); 81 | } 82 | 83 | /** 84 | * Parse input 85 | * 86 | * This method will attempt to parse the request body 87 | * based on its content type if available. 88 | * 89 | * @param string $input 90 | * @param string $contentType 91 | * @return mixed 92 | */ 93 | protected function parse ($input, $contentType) 94 | { 95 | if (isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType])) { 96 | $result = call_user_func($this->contentTypes[$contentType], $input); 97 | if ($result) { 98 | return $result; 99 | } 100 | } 101 | 102 | return $input; 103 | } 104 | 105 | /** 106 | * Parse JSON 107 | * 108 | * This method converts the raw JSON input 109 | * into an associative array. 110 | * 111 | * @param string $input 112 | * @return array|string 113 | */ 114 | protected function parseJson($input) 115 | { 116 | if (function_exists('json_decode')) { 117 | $result = json_decode($input, true); 118 | if ($result) { 119 | return $result; 120 | } 121 | } 122 | } 123 | 124 | /** 125 | * Parse XML 126 | * 127 | * This method creates a SimpleXMLElement 128 | * based upon the XML input. If the SimpleXML 129 | * extension is not available, the raw input 130 | * will be returned unchanged. 131 | * 132 | * @param string $input 133 | * @return \SimpleXMLElement|string 134 | */ 135 | protected function parseXml($input) 136 | { 137 | if (class_exists('SimpleXMLElement')) { 138 | try { 139 | return new \SimpleXMLElement($input); 140 | } catch (\Exception $e) { 141 | // Do nothing 142 | } 143 | } 144 | 145 | return $input; 146 | } 147 | 148 | /** 149 | * Parse CSV 150 | * 151 | * This method parses CSV content into a numeric array 152 | * containing an array of data for each CSV line. 153 | * 154 | * @param string $input 155 | * @return array 156 | */ 157 | protected function parseCsv($input) 158 | { 159 | $temp = fopen('php://memory', 'rw'); 160 | fwrite($temp, $input); 161 | fseek($temp, 0); 162 | $res = array(); 163 | while (($data = fgetcsv($temp)) !== false) { 164 | $res[] = $data; 165 | } 166 | fclose($temp); 167 | 168 | return $res; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /sales-server/Slim/Middleware/Flash.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Middleware; 34 | 35 | /** 36 | * Flash 37 | * 38 | * This is middleware for a Slim application that enables 39 | * Flash messaging between HTTP requests. This allows you 40 | * set Flash messages for the current request, for the next request, 41 | * or to retain messages from the previous request through to 42 | * the next request. 43 | * 44 | * @package Slim 45 | * @author Josh Lockhart 46 | * @since 1.6.0 47 | */ 48 | class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate 49 | { 50 | /** 51 | * @var array 52 | */ 53 | protected $settings; 54 | 55 | /** 56 | * @var array 57 | */ 58 | protected $messages; 59 | 60 | /** 61 | * Constructor 62 | * @param \Slim $app 63 | * @param array $settings 64 | */ 65 | public function __construct($settings = array()) 66 | { 67 | $this->settings = array_merge(array('key' => 'slim.flash'), $settings); 68 | $this->messages = array( 69 | 'prev' => array(), //flash messages from prev request (loaded when middleware called) 70 | 'next' => array(), //flash messages for next request 71 | 'now' => array() //flash messages for current request 72 | ); 73 | } 74 | 75 | /** 76 | * Call 77 | */ 78 | public function call() 79 | { 80 | //Read flash messaging from previous request if available 81 | $this->loadMessages(); 82 | 83 | //Prepare flash messaging for current request 84 | $env = $this->app->environment(); 85 | $env['slim.flash'] = $this; 86 | $this->next->call(); 87 | $this->save(); 88 | } 89 | 90 | /** 91 | * Now 92 | * 93 | * Specify a flash message for a given key to be shown for the current request 94 | * 95 | * @param string $key 96 | * @param string $value 97 | */ 98 | public function now($key, $value) 99 | { 100 | $this->messages['now'][(string) $key] = $value; 101 | } 102 | 103 | /** 104 | * Set 105 | * 106 | * Specify a flash message for a given key to be shown for the next request 107 | * 108 | * @param string $key 109 | * @param string $value 110 | */ 111 | public function set($key, $value) 112 | { 113 | $this->messages['next'][(string) $key] = $value; 114 | } 115 | 116 | /** 117 | * Keep 118 | * 119 | * Retain flash messages from the previous request for the next request 120 | */ 121 | public function keep() 122 | { 123 | foreach ($this->messages['prev'] as $key => $val) { 124 | $this->messages['next'][$key] = $val; 125 | } 126 | } 127 | 128 | /** 129 | * Save 130 | */ 131 | public function save() 132 | { 133 | $_SESSION[$this->settings['key']] = $this->messages['next']; 134 | } 135 | 136 | /** 137 | * Load messages from previous request if available 138 | */ 139 | public function loadMessages() 140 | { 141 | if (isset($_SESSION[$this->settings['key']])) { 142 | $this->messages['prev'] = $_SESSION[$this->settings['key']]; 143 | } 144 | } 145 | 146 | /** 147 | * Return array of flash messages to be shown for the current request 148 | * 149 | * @return array 150 | */ 151 | public function getMessages() 152 | { 153 | return array_merge($this->messages['prev'], $this->messages['now']); 154 | } 155 | 156 | /** 157 | * Array Access: Offset Exists 158 | */ 159 | public function offsetExists($offset) 160 | { 161 | $messages = $this->getMessages(); 162 | 163 | return isset($messages[$offset]); 164 | } 165 | 166 | /** 167 | * Array Access: Offset Get 168 | */ 169 | public function offsetGet($offset) 170 | { 171 | $messages = $this->getMessages(); 172 | 173 | return isset($messages[$offset]) ? $messages[$offset] : null; 174 | } 175 | 176 | /** 177 | * Array Access: Offset Set 178 | */ 179 | public function offsetSet($offset, $value) 180 | { 181 | $this->now($offset, $value); 182 | } 183 | 184 | /** 185 | * Array Access: Offset Unset 186 | */ 187 | public function offsetUnset($offset) 188 | { 189 | unset($this->messages['prev'][$offset], $this->messages['now'][$offset]); 190 | } 191 | 192 | /** 193 | * Iterator Aggregate: Get Iterator 194 | * @return \ArrayIterator 195 | */ 196 | public function getIterator() 197 | { 198 | $messages = $this->getMessages(); 199 | 200 | return new \ArrayIterator($messages); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /sales-server/Slim/Middleware/MethodOverride.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Middleware; 34 | 35 | /** 36 | * HTTP Method Override 37 | * 38 | * This is middleware for a Slim application that allows traditional 39 | * desktop browsers to submit psuedo PUT and DELETE requests by relying 40 | * on a pre-determined request parameter. Without this middleware, 41 | * desktop browsers are only able to submit GET and POST requests. 42 | * 43 | * This middleware is included automatically! 44 | * 45 | * @package Slim 46 | * @author Josh Lockhart 47 | * @since 1.6.0 48 | */ 49 | class MethodOverride extends \Slim\Middleware 50 | { 51 | /** 52 | * @var array 53 | */ 54 | protected $settings; 55 | 56 | /** 57 | * Constructor 58 | * @param \Slim $app 59 | * @param array $settings 60 | */ 61 | public function __construct($settings = array()) 62 | { 63 | $this->settings = array_merge(array('key' => '_METHOD'), $settings); 64 | } 65 | 66 | /** 67 | * Call 68 | * 69 | * Implements Slim middleware interface. This method is invoked and passed 70 | * an array of environment variables. This middleware inspects the environment 71 | * variables for the HTTP method override parameter; if found, this middleware 72 | * modifies the environment settings so downstream middleware and/or the Slim 73 | * application will treat the request with the desired HTTP method. 74 | * 75 | * @param array $env 76 | * @return array[status, header, body] 77 | */ 78 | public function call() 79 | { 80 | $env = $this->app->environment(); 81 | if (isset($env['X_HTTP_METHOD_OVERRIDE'])) { 82 | // Header commonly used by Backbone.js and others 83 | $env['slim.method_override.original_method'] = $env['REQUEST_METHOD']; 84 | $env['REQUEST_METHOD'] = strtoupper($env['X_HTTP_METHOD_OVERRIDE']); 85 | } elseif (isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST') { 86 | // HTML Form Override 87 | $req = new \Slim\Http\Request($env); 88 | $method = $req->post($this->settings['key']); 89 | if ($method) { 90 | $env['slim.method_override.original_method'] = $env['REQUEST_METHOD']; 91 | $env['REQUEST_METHOD'] = strtoupper($method); 92 | } 93 | } 94 | $this->next->call(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /sales-server/Slim/Middleware/PrettyExceptions.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Middleware; 34 | 35 | /** 36 | * Pretty Exceptions 37 | * 38 | * This middleware catches any Exception thrown by the surrounded 39 | * application and displays a developer-friendly diagnostic screen. 40 | * 41 | * @package Slim 42 | * @author Josh Lockhart 43 | * @since 1.0.0 44 | */ 45 | class PrettyExceptions extends \Slim\Middleware 46 | { 47 | /** 48 | * @var array 49 | */ 50 | protected $settings; 51 | 52 | /** 53 | * Constructor 54 | * @param array $settings 55 | */ 56 | public function __construct($settings = array()) 57 | { 58 | $this->settings = $settings; 59 | } 60 | 61 | /** 62 | * Call 63 | */ 64 | public function call() 65 | { 66 | try { 67 | $this->next->call(); 68 | } catch (\Exception $e) { 69 | $env = $this->app->environment(); 70 | $env['slim.log']->error($e); 71 | $this->app->contentType('text/html'); 72 | $this->app->response()->status(500); 73 | $this->app->response()->body($this->renderBody($env, $e)); 74 | } 75 | } 76 | 77 | /** 78 | * Render response body 79 | * @param array $env 80 | * @param \Exception $exception 81 | * @return string 82 | */ 83 | protected function renderBody(&$env, $exception) 84 | { 85 | $title = 'Slim Application Error'; 86 | $code = $exception->getCode(); 87 | $message = $exception->getMessage(); 88 | $file = $exception->getFile(); 89 | $line = $exception->getLine(); 90 | $trace = $exception->getTraceAsString(); 91 | $html = sprintf('

%s

', $title); 92 | $html .= '

The application could not run because of the following error:

'; 93 | $html .= '

Details

'; 94 | $html .= sprintf('
Type: %s
', get_class($exception)); 95 | if ($code) { 96 | $html .= sprintf('
Code: %s
', $code); 97 | } 98 | if ($message) { 99 | $html .= sprintf('
Message: %s
', $message); 100 | } 101 | if ($file) { 102 | $html .= sprintf('
File: %s
', $file); 103 | } 104 | if ($line) { 105 | $html .= sprintf('
Line: %s
', $line); 106 | } 107 | if ($trace) { 108 | $html .= '

Trace

'; 109 | $html .= sprintf('
%s
', $trace); 110 | } 111 | 112 | return sprintf("%s%s", $title, $html); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /sales-server/Slim/Middleware/SessionCookie.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim\Middleware; 34 | 35 | /** 36 | * Session Cookie 37 | * 38 | * This class provides an HTTP cookie storage mechanism 39 | * for session data. This class avoids using a PHP session 40 | * and instead serializes/unserializes the $_SESSION global 41 | * variable to/from an HTTP cookie. 42 | * 43 | * If a secret key is provided with this middleware, the HTTP 44 | * cookie will be checked for integrity to ensure the client-side 45 | * cookie is not changed. 46 | * 47 | * You should NEVER store sensitive data in a client-side cookie 48 | * in any format, encrypted or not. If you need to store sensitive 49 | * user information in a session, you should rely on PHP's native 50 | * session implementation, or use other middleware to store 51 | * session data in a database or alternative server-side cache. 52 | * 53 | * Because this class stores serialized session data in an HTTP cookie, 54 | * you are inherently limtied to 4 Kb. If you attempt to store 55 | * more than this amount, serialization will fail. 56 | * 57 | * @package Slim 58 | * @author Josh Lockhart 59 | * @since 1.6.0 60 | */ 61 | class SessionCookie extends \Slim\Middleware 62 | { 63 | /** 64 | * @var array 65 | */ 66 | protected $settings; 67 | 68 | /** 69 | * Constructor 70 | * 71 | * @param array $settings 72 | */ 73 | public function __construct($settings = array()) 74 | { 75 | $this->settings = array_merge(array( 76 | 'expires' => '20 minutes', 77 | 'path' => '/', 78 | 'domain' => null, 79 | 'secure' => false, 80 | 'httponly' => false, 81 | 'name' => 'slim_session', 82 | 'secret' => 'CHANGE_ME', 83 | 'cipher' => MCRYPT_RIJNDAEL_256, 84 | 'cipher_mode' => MCRYPT_MODE_CBC 85 | ), $settings); 86 | if (is_string($this->settings['expires'])) { 87 | $this->settings['expires'] = strtotime($this->settings['expires']); 88 | } 89 | 90 | /** 91 | * Session 92 | * 93 | * We must start a native PHP session to initialize the $_SESSION superglobal. 94 | * However, we won't be using the native session store for persistence, so we 95 | * disable the session cookie and cache limiter. We also set the session 96 | * handler to this class instance to avoid PHP's native session file locking. 97 | */ 98 | ini_set('session.use_cookies', 0); 99 | session_cache_limiter(false); 100 | session_set_save_handler( 101 | array($this, 'open'), 102 | array($this, 'close'), 103 | array($this, 'read'), 104 | array($this, 'write'), 105 | array($this, 'destroy'), 106 | array($this, 'gc') 107 | ); 108 | } 109 | 110 | /** 111 | * Call 112 | */ 113 | public function call() 114 | { 115 | $this->loadSession(); 116 | $this->next->call(); 117 | $this->saveSession(); 118 | } 119 | 120 | /** 121 | * Load session 122 | * @param array $env 123 | */ 124 | protected function loadSession() 125 | { 126 | if (session_id() === '') { 127 | session_start(); 128 | } 129 | 130 | $value = \Slim\Http\Util::decodeSecureCookie( 131 | $this->app->request()->cookies($this->settings['name']), 132 | $this->settings['secret'], 133 | $this->settings['cipher'], 134 | $this->settings['cipher_mode'] 135 | ); 136 | if ($value) { 137 | $_SESSION = unserialize($value); 138 | } else { 139 | $_SESSION = array(); 140 | } 141 | } 142 | 143 | /** 144 | * Save session 145 | */ 146 | protected function saveSession() 147 | { 148 | $value = \Slim\Http\Util::encodeSecureCookie( 149 | serialize($_SESSION), 150 | $this->settings['expires'], 151 | $this->settings['secret'], 152 | $this->settings['cipher'], 153 | $this->settings['cipher_mode'] 154 | ); 155 | if (strlen($value) > 4096) { 156 | $this->app->getLog()->error('WARNING! Slim\Middleware\SessionCookie data size is larger than 4KB. Content save failed.'); 157 | } else { 158 | $this->app->response()->setCookie($this->settings['name'], array( 159 | 'value' => $value, 160 | 'domain' => $this->settings['domain'], 161 | 'path' => $this->settings['path'], 162 | 'expires' => $this->settings['expires'], 163 | 'secure' => $this->settings['secure'], 164 | 'httponly' => $this->settings['httponly'] 165 | )); 166 | } 167 | session_destroy(); 168 | } 169 | 170 | /******************************************************************************** 171 | * Session Handler 172 | *******************************************************************************/ 173 | 174 | public function open($savePath, $sessionName) 175 | { 176 | return true; 177 | } 178 | 179 | public function close() 180 | { 181 | return true; 182 | } 183 | 184 | public function read($id) 185 | { 186 | return ''; 187 | } 188 | 189 | public function write($id, $data) 190 | { 191 | return true; 192 | } 193 | 194 | public function destroy($id) 195 | { 196 | return true; 197 | } 198 | 199 | public function gc($maxlifetime) 200 | { 201 | return true; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /sales-server/Slim/Route.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.0.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * Route 37 | * @package Slim 38 | * @author Josh Lockhart, Thomas Bley 39 | * @since 1.0.0 40 | */ 41 | class Route 42 | { 43 | /** 44 | * @var string The route pattern (e.g. "/books/:id") 45 | */ 46 | protected $pattern; 47 | 48 | /** 49 | * @var mixed The route callable 50 | */ 51 | protected $callable; 52 | 53 | /** 54 | * @var array Conditions for this route's URL parameters 55 | */ 56 | protected $conditions = array(); 57 | 58 | /** 59 | * @var array Default conditions applied to all route instances 60 | */ 61 | protected static $defaultConditions = array(); 62 | 63 | /** 64 | * @var string The name of this route (optional) 65 | */ 66 | protected $name; 67 | 68 | /** 69 | * @var array Key-value array of URL parameters 70 | */ 71 | protected $params = array(); 72 | 73 | /** 74 | * @var array value array of URL parameter names 75 | */ 76 | protected $paramNames = array(); 77 | 78 | /** 79 | * @var array key array of URL parameter names with + at the end 80 | */ 81 | protected $paramNamesPath = array(); 82 | 83 | /** 84 | * @var array HTTP methods supported by this Route 85 | */ 86 | protected $methods = array(); 87 | 88 | /** 89 | * @var array[Callable] Middleware to be run before only this route instance 90 | */ 91 | protected $middleware = array(); 92 | 93 | /** 94 | * Constructor 95 | * @param string $pattern The URL pattern (e.g. "/books/:id") 96 | * @param mixed $callable Anything that returns TRUE for is_callable() 97 | */ 98 | public function __construct($pattern, $callable) 99 | { 100 | $this->setPattern($pattern); 101 | $this->setCallable($callable); 102 | $this->setConditions(self::getDefaultConditions()); 103 | } 104 | 105 | /** 106 | * Set default route conditions for all instances 107 | * @param array $defaultConditions 108 | */ 109 | public static function setDefaultConditions(array $defaultConditions) 110 | { 111 | self::$defaultConditions = $defaultConditions; 112 | } 113 | 114 | /** 115 | * Get default route conditions for all instances 116 | * @return array 117 | */ 118 | public static function getDefaultConditions() 119 | { 120 | return self::$defaultConditions; 121 | } 122 | 123 | /** 124 | * Get route pattern 125 | * @return string 126 | */ 127 | public function getPattern() 128 | { 129 | return $this->pattern; 130 | } 131 | 132 | /** 133 | * Set route pattern 134 | * @param string $pattern 135 | */ 136 | public function setPattern($pattern) 137 | { 138 | $this->pattern = $pattern; 139 | } 140 | 141 | /** 142 | * Get route callable 143 | * @return mixed 144 | */ 145 | public function getCallable() 146 | { 147 | return $this->callable; 148 | } 149 | 150 | /** 151 | * Set route callable 152 | * @param mixed $callable 153 | * @throws \InvalidArgumentException If argument is not callable 154 | */ 155 | public function setCallable($callable) 156 | { 157 | if (!is_callable($callable)) { 158 | throw new \InvalidArgumentException('Route callable must be callable'); 159 | } 160 | 161 | $this->callable = $callable; 162 | } 163 | 164 | /** 165 | * Get route conditions 166 | * @return array 167 | */ 168 | public function getConditions() 169 | { 170 | return $this->conditions; 171 | } 172 | 173 | /** 174 | * Set route conditions 175 | * @param array $conditions 176 | */ 177 | public function setConditions(array $conditions) 178 | { 179 | $this->conditions = $conditions; 180 | } 181 | 182 | /** 183 | * Get route name 184 | * @return string|null 185 | */ 186 | public function getName() 187 | { 188 | return $this->name; 189 | } 190 | 191 | /** 192 | * Set route name 193 | * @param string $name 194 | */ 195 | public function setName($name) 196 | { 197 | $this->name = (string) $name; 198 | } 199 | 200 | /** 201 | * Get route parameters 202 | * @return array 203 | */ 204 | public function getParams() 205 | { 206 | return $this->params; 207 | } 208 | 209 | /** 210 | * Set route parameters 211 | * @param array $params 212 | */ 213 | public function setParams($params) 214 | { 215 | $this->params = $params; 216 | } 217 | 218 | /** 219 | * Get route parameter value 220 | * @param string $index Name of URL parameter 221 | * @return string 222 | * @throws \InvalidArgumentException If route parameter does not exist at index 223 | */ 224 | public function getParam($index) 225 | { 226 | if (!isset($this->params[$index])) { 227 | throw new \InvalidArgumentException('Route parameter does not exist at specified index'); 228 | } 229 | 230 | return $this->params[$index]; 231 | } 232 | 233 | /** 234 | * Set route parameter value 235 | * @param string $index Name of URL parameter 236 | * @param mixed $value The new parameter value 237 | * @throws \InvalidArgumentException If route parameter does not exist at index 238 | */ 239 | public function setParam($index, $value) 240 | { 241 | if (!isset($this->params[$index])) { 242 | throw new \InvalidArgumentException('Route parameter does not exist at specified index'); 243 | } 244 | $this->params[$index] = $value; 245 | } 246 | 247 | /** 248 | * Add supported HTTP method(s) 249 | */ 250 | public function setHttpMethods() 251 | { 252 | $args = func_get_args(); 253 | $this->methods = $args; 254 | } 255 | 256 | /** 257 | * Get supported HTTP methods 258 | * @return array 259 | */ 260 | public function getHttpMethods() 261 | { 262 | return $this->methods; 263 | } 264 | 265 | /** 266 | * Append supported HTTP methods 267 | */ 268 | public function appendHttpMethods() 269 | { 270 | $args = func_get_args(); 271 | $this->methods = array_merge($this->methods, $args); 272 | } 273 | 274 | /** 275 | * Append supported HTTP methods (alias for Route::appendHttpMethods) 276 | * @return \Slim\Route 277 | */ 278 | public function via() 279 | { 280 | $args = func_get_args(); 281 | $this->methods = array_merge($this->methods, $args); 282 | 283 | return $this; 284 | } 285 | 286 | /** 287 | * Detect support for an HTTP method 288 | * @return bool 289 | */ 290 | public function supportsHttpMethod($method) 291 | { 292 | return in_array($method, $this->methods); 293 | } 294 | 295 | /** 296 | * Get middleware 297 | * @return array[Callable] 298 | */ 299 | public function getMiddleware() 300 | { 301 | return $this->middleware; 302 | } 303 | 304 | /** 305 | * Set middleware 306 | * 307 | * This method allows middleware to be assigned to a specific Route. 308 | * If the method argument `is_callable` (including callable arrays!), 309 | * we directly append the argument to `$this->middleware`. Else, we 310 | * assume the argument is an array of callables and merge the array 311 | * with `$this->middleware`. Each middleware is checked for is_callable() 312 | * and an InvalidArgumentException is thrown immediately if it isn't. 313 | * 314 | * @param Callable|array[Callable] 315 | * @return \Slim\Route 316 | * @throws \InvalidArgumentException If argument is not callable or not an array of callables. 317 | */ 318 | public function setMiddleware($middleware) 319 | { 320 | if (is_callable($middleware)) { 321 | $this->middleware[] = $middleware; 322 | } elseif (is_array($middleware)) { 323 | foreach($middleware as $callable) { 324 | if (!is_callable($callable)) { 325 | throw new \InvalidArgumentException('All Route middleware must be callable'); 326 | } 327 | } 328 | $this->middleware = array_merge($this->middleware, $middleware); 329 | } else { 330 | throw new \InvalidArgumentException('Route middleware must be callable or an array of callables'); 331 | } 332 | 333 | return $this; 334 | } 335 | 336 | /** 337 | * Matches URI? 338 | * 339 | * Parse this route's pattern, and then compare it to an HTTP resource URI 340 | * This method was modeled after the techniques demonstrated by Dan Sosedoff at: 341 | * 342 | * http://blog.sosedoff.com/2009/09/20/rails-like-php-url-router/ 343 | * 344 | * @param string $resourceUri A Request URI 345 | * @return bool 346 | */ 347 | public function matches($resourceUri) 348 | { 349 | //Convert URL params into regex patterns, construct a regex for this route, init params 350 | $patternAsRegex = preg_replace_callback('#:([\w]+)\+?#', array($this, 'matchesCallback'), 351 | str_replace(')', ')?', (string) $this->pattern)); 352 | if (substr($this->pattern, -1) === '/') { 353 | $patternAsRegex .= '?'; 354 | } 355 | 356 | //Cache URL params' names and values if this route matches the current HTTP request 357 | if (!preg_match('#^' . $patternAsRegex . '$#', $resourceUri, $paramValues)) { 358 | return false; 359 | } 360 | foreach ($this->paramNames as $name) { 361 | if (isset($paramValues[$name])) { 362 | if (isset($this->paramNamesPath[ $name ])) { 363 | $this->params[$name] = explode('/', urldecode($paramValues[$name])); 364 | } else { 365 | $this->params[$name] = urldecode($paramValues[$name]); 366 | } 367 | } 368 | } 369 | 370 | return true; 371 | } 372 | 373 | /** 374 | * Convert a URL parameter (e.g. ":id", ":id+") into a regular expression 375 | * @param array URL parameters 376 | * @return string Regular expression for URL parameter 377 | */ 378 | protected function matchesCallback($m) 379 | { 380 | $this->paramNames[] = $m[1]; 381 | if (isset($this->conditions[ $m[1] ])) { 382 | return '(?P<' . $m[1] . '>' . $this->conditions[ $m[1] ] . ')'; 383 | } 384 | if (substr($m[0], -1) === '+') { 385 | $this->paramNamesPath[ $m[1] ] = 1; 386 | 387 | return '(?P<' . $m[1] . '>.+)'; 388 | } 389 | 390 | return '(?P<' . $m[1] . '>[^/]+)'; 391 | } 392 | 393 | /** 394 | * Set route name 395 | * @param string $name The name of the route 396 | * @return \Slim\Route 397 | */ 398 | public function name($name) 399 | { 400 | $this->setName($name); 401 | 402 | return $this; 403 | } 404 | 405 | /** 406 | * Merge route conditions 407 | * @param array $conditions Key-value array of URL parameter conditions 408 | * @return \Slim\Route 409 | */ 410 | public function conditions(array $conditions) 411 | { 412 | $this->conditions = array_merge($this->conditions, $conditions); 413 | 414 | return $this; 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /sales-server/Slim/Router.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * Router 37 | * 38 | * This class organizes, iterates, and dispatches \Slim\Route objects. 39 | * 40 | * @package Slim 41 | * @author Josh Lockhart 42 | * @since 1.0.0 43 | */ 44 | class Router 45 | { 46 | /** 47 | * @var Route The current route (most recently dispatched) 48 | */ 49 | protected $currentRoute; 50 | 51 | /** 52 | * @var array Lookup hash of all route objects 53 | */ 54 | protected $routes; 55 | 56 | /** 57 | * @var array Lookup hash of named route objects, keyed by route name (lazy-loaded) 58 | */ 59 | protected $namedRoutes; 60 | 61 | /** 62 | * @var array Array of route objects that match the request URI (lazy-loaded) 63 | */ 64 | protected $matchedRoutes; 65 | 66 | /** 67 | * Constructor 68 | */ 69 | public function __construct() 70 | { 71 | $this->routes = array(); 72 | } 73 | 74 | /** 75 | * Get Current Route object or the first matched one if matching has been performed 76 | * @return \Slim\Route|null 77 | */ 78 | public function getCurrentRoute() 79 | { 80 | if ($this->currentRoute !== null) { 81 | return $this->currentRoute; 82 | } 83 | 84 | if (is_array($this->matchedRoutes) && count($this->matchedRoutes) > 0) { 85 | return $this->matchedRoutes[0]; 86 | } 87 | 88 | return null; 89 | } 90 | 91 | /** 92 | * Return route objects that match the given HTTP method and URI 93 | * @param string $httpMethod The HTTP method to match against 94 | * @param string $resourceUri The resource URI to match against 95 | * @param bool $reload Should matching routes be re-parsed? 96 | * @return array[\Slim\Route] 97 | */ 98 | public function getMatchedRoutes($httpMethod, $resourceUri, $reload = false) 99 | { 100 | if ($reload || is_null($this->matchedRoutes)) { 101 | $this->matchedRoutes = array(); 102 | foreach ($this->routes as $route) { 103 | if (!$route->supportsHttpMethod($httpMethod)) { 104 | continue; 105 | } 106 | 107 | if ($route->matches($resourceUri)) { 108 | $this->matchedRoutes[] = $route; 109 | } 110 | } 111 | } 112 | 113 | return $this->matchedRoutes; 114 | } 115 | 116 | /** 117 | * Map a route object to a callback function 118 | * @param string $pattern The URL pattern (ie. "/books/:id") 119 | * @param mixed $callable Anything that returns TRUE for is_callable() 120 | * @return \Slim\Route 121 | */ 122 | public function map($pattern, $callable) 123 | { 124 | $route = new \Slim\Route($pattern, $callable); 125 | $this->routes[] = $route; 126 | 127 | return $route; 128 | } 129 | 130 | /** 131 | * Get URL for named route 132 | * @param string $name The name of the route 133 | * @param array Associative array of URL parameter names and replacement values 134 | * @throws RuntimeException If named route not found 135 | * @return string The URL for the given route populated with provided replacement values 136 | */ 137 | public function urlFor($name, $params = array()) 138 | { 139 | if (!$this->hasNamedRoute($name)) { 140 | throw new \RuntimeException('Named route not found for name: ' . $name); 141 | } 142 | $search = array(); 143 | foreach (array_keys($params) as $key) { 144 | $search[] = '#:' . $key . '\+?(?!\w)#'; 145 | } 146 | $pattern = preg_replace($search, $params, $this->getNamedRoute($name)->getPattern()); 147 | 148 | //Remove remnants of unpopulated, trailing optional pattern segments 149 | return preg_replace('#\(/?:.+\)|\(|\)#', '', $pattern); 150 | } 151 | 152 | /** 153 | * Dispatch route 154 | * 155 | * This method invokes the route object's callable. If middleware is 156 | * registered for the route, each callable middleware is invoked in 157 | * the order specified. 158 | * 159 | * @param \Slim\Route $route The route object 160 | * @return bool Was route callable invoked successfully? 161 | */ 162 | public function dispatch(\Slim\Route $route) 163 | { 164 | $this->currentRoute = $route; 165 | 166 | //Invoke middleware 167 | foreach ($route->getMiddleware() as $mw) { 168 | call_user_func_array($mw, array($route)); 169 | } 170 | 171 | //Invoke callable 172 | call_user_func_array($route->getCallable(), array_values($route->getParams())); 173 | 174 | return true; 175 | } 176 | 177 | /** 178 | * Add named route 179 | * @param string $name The route name 180 | * @param \Slim\Route $route The route object 181 | * @throws \RuntimeException If a named route already exists with the same name 182 | */ 183 | public function addNamedRoute($name, \Slim\Route $route) 184 | { 185 | if ($this->hasNamedRoute($name)) { 186 | throw new \RuntimeException('Named route already exists with name: ' . $name); 187 | } 188 | $this->namedRoutes[(string) $name] = $route; 189 | } 190 | 191 | /** 192 | * Has named route 193 | * @param string $name The route name 194 | * @return bool 195 | */ 196 | public function hasNamedRoute($name) 197 | { 198 | $this->getNamedRoutes(); 199 | 200 | return isset($this->namedRoutes[(string) $name]); 201 | } 202 | 203 | /** 204 | * Get named route 205 | * @param string $name 206 | * @return \Slim\Route|null 207 | */ 208 | public function getNamedRoute($name) 209 | { 210 | $this->getNamedRoutes(); 211 | if ($this->hasNamedRoute($name)) { 212 | return $this->namedRoutes[(string) $name]; 213 | } else { 214 | return null; 215 | } 216 | } 217 | 218 | /** 219 | * Get named routes 220 | * @return \ArrayIterator 221 | */ 222 | public function getNamedRoutes() 223 | { 224 | if (is_null($this->namedRoutes)) { 225 | $this->namedRoutes = array(); 226 | foreach ($this->routes as $route) { 227 | if ($route->getName() !== null) { 228 | $this->addNamedRoute($route->getName(), $route); 229 | } 230 | } 231 | } 232 | 233 | return new \ArrayIterator($this->namedRoutes); 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /sales-server/Slim/View.php: -------------------------------------------------------------------------------- 1 | 6 | * @copyright 2011 Josh Lockhart 7 | * @link http://www.slimframework.com 8 | * @license http://www.slimframework.com/license 9 | * @version 2.2.0 10 | * @package Slim 11 | * 12 | * MIT LICENSE 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining 15 | * a copy of this software and associated documentation files (the 16 | * "Software"), to deal in the Software without restriction, including 17 | * without limitation the rights to use, copy, modify, merge, publish, 18 | * distribute, sublicense, and/or sell copies of the Software, and to 19 | * permit persons to whom the Software is furnished to do so, subject to 20 | * the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be 23 | * included in all copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | namespace Slim; 34 | 35 | /** 36 | * View 37 | * 38 | * The view is responsible for rendering a template. The view 39 | * should subclass \Slim\View and implement this interface: 40 | * 41 | * public render(string $template); 42 | * 43 | * This method should render the specified template and return 44 | * the resultant string. 45 | * 46 | * @package Slim 47 | * @author Josh Lockhart 48 | * @since 1.0.0 49 | */ 50 | class View 51 | { 52 | /** 53 | * @var string Absolute or relative filesystem path to a specific template 54 | * 55 | * DEPRECATION WARNING! 56 | * This variable will be removed in the near future 57 | */ 58 | protected $templatePath = ''; 59 | 60 | /** 61 | * @var array Associative array of template variables 62 | */ 63 | protected $data = array(); 64 | 65 | /** 66 | * @var string Absolute or relative path to the application's templates directory 67 | */ 68 | protected $templatesDirectory; 69 | 70 | /** 71 | * Constructor 72 | * 73 | * This is empty but may be implemented in a subclass 74 | */ 75 | public function __construct() 76 | { 77 | 78 | } 79 | 80 | /** 81 | * Get data 82 | * @param string|null $key 83 | * @return mixed If key is null, array of template data; 84 | * If key exists, value of datum with key; 85 | * If key does not exist, null; 86 | */ 87 | public function getData($key = null) 88 | { 89 | if (!is_null($key)) { 90 | return isset($this->data[$key]) ? $this->data[$key] : null; 91 | } else { 92 | return $this->data; 93 | } 94 | } 95 | 96 | /** 97 | * Set data 98 | * 99 | * If two arguments: 100 | * A single datum with key is assigned value; 101 | * 102 | * $view->setData('color', 'red'); 103 | * 104 | * If one argument: 105 | * Replace all data with provided array keys and values; 106 | * 107 | * $view->setData(array('color' => 'red', 'number' => 1)); 108 | * 109 | * @param mixed 110 | * @param mixed 111 | * @throws InvalidArgumentException If incorrect method signature 112 | */ 113 | public function setData() 114 | { 115 | $args = func_get_args(); 116 | if (count($args) === 1 && is_array($args[0])) { 117 | $this->data = $args[0]; 118 | } elseif (count($args) === 2) { 119 | $this->data[(string) $args[0]] = $args[1]; 120 | } else { 121 | throw new \InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`'); 122 | } 123 | } 124 | 125 | /** 126 | * Append new data to existing template data 127 | * @param array 128 | * @throws InvalidArgumentException If not given an array argument 129 | */ 130 | public function appendData($data) 131 | { 132 | if (!is_array($data)) { 133 | throw new \InvalidArgumentException('Cannot append view data. Expected array argument.'); 134 | } 135 | $this->data = array_merge($this->data, $data); 136 | } 137 | 138 | /** 139 | * Get templates directory 140 | * @return string|null Path to templates directory without trailing slash; 141 | * Returns null if templates directory not set; 142 | */ 143 | public function getTemplatesDirectory() 144 | { 145 | return $this->templatesDirectory; 146 | } 147 | 148 | /** 149 | * Set templates directory 150 | * @param string $dir 151 | */ 152 | public function setTemplatesDirectory($dir) 153 | { 154 | $this->templatesDirectory = rtrim($dir, '/'); 155 | } 156 | 157 | /** 158 | * Set template 159 | * @param string $template 160 | * @throws RuntimeException If template file does not exist 161 | * 162 | * DEPRECATION WARNING! 163 | * This method will be removed in the near future. 164 | */ 165 | public function setTemplate($template) 166 | { 167 | $this->templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/'); 168 | if (!file_exists($this->templatePath)) { 169 | throw new \RuntimeException('View cannot render template `' . $this->templatePath . '`. Template does not exist.'); 170 | } 171 | } 172 | 173 | /** 174 | * Display template 175 | * 176 | * This method echoes the rendered template to the current output buffer 177 | * 178 | * @param string $template Pathname of template file relative to templates directoy 179 | */ 180 | public function display($template) 181 | { 182 | echo $this->fetch($template); 183 | } 184 | 185 | /** 186 | * Fetch rendered template 187 | * 188 | * This method returns the rendered template 189 | * 190 | * @param string $template Pathname of template file relative to templates directory 191 | * @return string 192 | */ 193 | public function fetch($template) 194 | { 195 | return $this->render($template); 196 | } 197 | 198 | /** 199 | * Render template 200 | * 201 | * @param string $template Pathname of template file relative to templates directory 202 | * @return string 203 | * 204 | * DEPRECATION WARNING! 205 | * Use `\Slim\View::fetch` to return a rendered template instead of `\Slim\View::render`. 206 | */ 207 | public function render($template) 208 | { 209 | $this->setTemplate($template); 210 | extract($this->data); 211 | ob_start(); 212 | require $this->templatePath; 213 | 214 | return ob_get_clean(); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /sales-server/config.php: -------------------------------------------------------------------------------- 1 | get("/customers",function (){ 4 | 5 | $sql = "SELECT CustomerID,ContactName,Phone FROM customers"; 6 | $stmt = DB::prepare($sql); 7 | $stmt->execute(); 8 | formatJson($stmt->fetchAll()); 9 | }); 10 | 11 | $app->get("/customer/:id",function ($id){ 12 | 13 | $sql = "SELECT CustomerID,ContactName,Phone FROM customers WHERE CustomerID='$id'"; 14 | $stmt = DB::prepare($sql); 15 | $stmt->execute(); 16 | formatJson($stmt->fetch()); 17 | }); 18 | 19 | $app->post("/customer/:id",function ($id){ 20 | 21 | $data =json_decode(\Slim\Slim::getInstance()->request()->getBody()); 22 | 23 | if ($data->isUpdate) 24 | { 25 | $sql = "UPDATE customers SET ContactName=?,Phone=? WHERE CustomerID=?"; 26 | $stmt = DB::prepare($sql); 27 | $stmt->execute(array( 28 | $data->ContactName, 29 | $data->Phone, 30 | $data->CustomerID 31 | ) 32 | ); 33 | } 34 | else 35 | { 36 | $sql = "INSERT INTO customers (CustomerID,ContactName,Phone) VALUES (?,?,?)"; 37 | $stmt = DB::prepare($sql); 38 | $stmt->execute(array( 39 | $data->CustomerID, 40 | $data->ContactName, 41 | $data->Phone 42 | ) 43 | ); 44 | 45 | } 46 | 47 | formatJson($data); 48 | 49 | }); 50 | 51 | $app->delete("/customer/:id",function ($id){ 52 | $sql = "DELETE FROM customers WHERE CustomerID=?"; 53 | $stmt = DB::prepare($sql); 54 | $stmt->execute(array($id)); 55 | formatJson(true); 56 | }); 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /sales-server/employee.php: -------------------------------------------------------------------------------- 1 | get("/employees",function (){ 4 | 5 | $sql = "SELECT EmployeeID,FirstName,LastName,HomePhone FROM employees"; 6 | $stmt = DB::prepare($sql); 7 | $stmt->execute(); 8 | formatJson($stmt->fetchAll()); 9 | }); 10 | 11 | $app->get("/employee/:id",function ($id){ 12 | 13 | //DATE_FORMAT( `date` , '%d/%c/%Y %H:%i:%s' ) AS `date` 14 | $sql = "SELECT EmployeeID,FirstName,LastName,HomePhone,DATE_FORMAT(BirthDate,'%d/%c/%Y') as BirthDate FROM employees WHERE EmployeeID=?"; 15 | $stmt = DB::prepare($sql); 16 | $stmt->execute(array($id)); 17 | formatJson($stmt->fetch()); 18 | }); 19 | 20 | $app->post("/employee/",function (){ 21 | 22 | $data =json_decode(\Slim\Slim::getInstance()->request()->getBody()); 23 | 24 | if ($data->EmployeeID!=0){ 25 | $sql = "UPDATE employees SET FirstName=?,LastName=?,HomePhone=?,BirthDate=? WHERE EmployeeID=?"; 26 | $stmt = DB::prepare($sql); 27 | $stmt->execute(array( 28 | $data->FirstName, 29 | $data->LastName, 30 | $data->HomePhone, 31 | DB::dateToMySql($data->BirthDate), 32 | $data->EmployeeID 33 | ) 34 | ); 35 | } 36 | else 37 | { 38 | $sql = "INSERT INTO employees (FirstName,LastName,HomePhone,BirthDate) VALUES (?,?,?,?)"; 39 | $stmt = DB::prepare($sql); 40 | $stmt->execute(array( 41 | $data->FirstName, 42 | $data->LastName, 43 | $data->HomePhone, 44 | DB::dateToMySql($data->BirthDate) 45 | ) 46 | ); 47 | $data->EmployeeID = DB::lastInsertId(); 48 | } 49 | 50 | formatJson($data); 51 | }); 52 | 53 | $app->delete("/employee/:id",function ($id){ 54 | $sql = "DELETE FROM customers WHERE CustomerID=?"; 55 | $stmt = DB::prepare($sql); 56 | $stmt->execute(array($id)); 57 | formatJson(true); 58 | }); 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /sales-server/index.php: -------------------------------------------------------------------------------- 1 | false 11 | )); 12 | 13 | $app->contentType("application/json"); 14 | 15 | $app->error(function ( Exception $e = null) use ($app) { 16 | echo '{"error":{"text":"'. $e->getMessage() .'"}}'; 17 | }); 18 | 19 | function formatJson($obj) 20 | { 21 | echo json_encode($obj); 22 | } 23 | 24 | //Includes 25 | include("customer.php"); 26 | include("employee.php"); 27 | 28 | 29 | $app->run(); -------------------------------------------------------------------------------- /sales/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sales", 3 | "version": "1.0.0", 4 | "description": "A sales app with node/express/mongodb", 5 | "main": "server.js", 6 | "scripts": { 7 | "build": "browserify -e src/index.js -o dist/build.js", 8 | "build-hmr": "watchify -vd -p browserify-hmr -e src/index.js -o dist/build.js", 9 | "server": "nodemon server.js", 10 | "dev": "npm-run-all --parallel build-hmr server" 11 | }, 12 | "author": "Daniel Schmitz", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "body-parser": "^1.15.2", 16 | "browserify": "^13.0.1", 17 | "browserify-hmr": "^0.3.1", 18 | "express": "^4.14.0", 19 | "jsonwebtoken": "^7.0.1", 20 | "mongoose": "^4.5.2", 21 | "nodemon": "^1.9.2", 22 | "npm-run-all": "^2.2.2", 23 | "watchify": "^3.7.0" 24 | }, 25 | "dependencies": { 26 | "angular": "^1.5.7" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sales/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sales App 5 | 6 | 7 |
8 | 9 | 10 |
11 |

Hello {{yourName}}!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /sales/router.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | 3 | router = express.Router(); 4 | 5 | //simple GET / 6 | router.get('/', function (req, res) { 7 | res.json({ message: 'hello world!' }); 8 | }); 9 | 10 | 11 | module.exports = router -------------------------------------------------------------------------------- /sales/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var bodyParser = require('body-parser'); 4 | var jwt = require('jsonwebtoken'); 5 | var mongoose = require('mongoose'); 6 | 7 | 8 | //Database in the cloud 9 | mongoose.connect('mongodb://localhost:27017/sales'); 10 | 11 | //webroot 12 | app.use('/', express.static(__dirname+'/public')); 13 | 14 | //router 15 | var router = require('./router') 16 | //router webroot 17 | app.use('/api', router); 18 | 19 | //start server 20 | var port = process.env.PORT || 8080; 21 | app.listen(port); 22 | console.log('WebServer listen: http://localhost:' + port); -------------------------------------------------------------------------------- /sales/src/index.js: -------------------------------------------------------------------------------- 1 | var angular = require("angular"); -------------------------------------------------------------------------------- /siteangular/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var concat = require('gulp-concat'); 3 | 4 | var js = [ 5 | './node_modules/angular/angular.min.js', 6 | './node_modules/bootstrap/dist/js/bootstrap.min.js' 7 | ]; 8 | 9 | //Cria a tarefa default 10 | gulp.task('default',function(){ 11 | gulp.src(js) 12 | .pipe(concat('script.min.js')) 13 | .pipe(gulp.dest('./js/')); 14 | }); -------------------------------------------------------------------------------- /siteangular/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | AngularJS 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /siteangular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "siteangular", 3 | "version": "0.0.0", 4 | "description": "Um site de teste", 5 | "main": "index.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Daniel", 10 | "license": "MIT", 11 | "dependencies": { 12 | "angular": "^1.4.7", 13 | "bootstrap": "^3.3.5" 14 | }, 15 | "devDependencies": { 16 | "gulp": "^3.9.0", 17 | "gulp-concat": "^2.6.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test-browserify/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test Browserify 5 | 6 | 7 |
8 | 9 | 10 |
11 |

Hello {{yourName}}!

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /test-browserify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-browserify", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "browserify -e src/index.js -o dist/build.js", 8 | "build-hmr": "watchify -vd -p browserify-hmr -e src/index.js -o dist/build.js", 9 | "server": "live-server", 10 | "dev": "npm-run-all --parallel build-hmr server" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "browserify": "^13.0.1", 16 | "browserify-hmr": "^0.3.1", 17 | "live-server": "^1.0.0", 18 | "npm-run-all": "^2.2.2", 19 | "watchify": "^3.7.0" 20 | }, 21 | "dependencies": { 22 | "angular": "^1.5.7" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test-browserify/src/index.js: -------------------------------------------------------------------------------- 1 | var angular = require("angular") 2 | 3 | 4 | console.log("Hello World"); --------------------------------------------------------------------------------