diff --git a/.bowerrc b/.bowerrc index 8c48f3541136..7694ad7822ba 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,3 +1,3 @@ { - "directory": "resources/assets/bower" + "directory": "./public/vendor" } \ No newline at end of file diff --git a/.gitignore b/.gitignore index f1594640bb7c..09e1dfee7b58 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ /public/build /public/packages /public/vendor -/resources/assets/bower /storage /bootstrap/compiled.php /bootstrap/environment.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c71e47891557..6100d090e1ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Auto billing uses credits if they exist -- All assets (CSS, JS) are minfied now - - ## [2.6.4] - 2016-07-19 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7bc7ddd7110..0c2d0bbb7327 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ Thanks for your contributions! * Make your changes and commit * Check if your branch is still in sync with the repositorys **`develop`** branch * _Read:_ [Syncing a fork](https://help.github.com/articles/syncing-a-fork/) - * _Also read:_ [How to rebase a pull request](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request) + * _Also read:_ [How to rebase a pull request](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request) * Push your branch and create a PR against the Invoice Ninja **`develop`** branch * Update the [Changelog](CHANGELOG.md) @@ -21,7 +21,7 @@ To make the contribution process nice and easy for anyone, please follow some ru to give a more detailed explanation. * Only one feature/bugfix per issue. If you want to submit more, create multiple issues. * Only one feature/bugfix per PR(pull request). Split more changes into multiple PRs. - + #### Coding Style Try to follow the [PSR-2 guidlines](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) @@ -29,7 +29,7 @@ _Example styling:_ ```php /** * Gets a preview of the email - * + * * @param TemplateService $templateService * * @return \Illuminate\Http\Response diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 000000000000..ce22ba6de51a --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,187 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + dump_dir: (function() { + var out = {}; + + grunt.file.expand({ filter: 'isDirectory'}, 'public/fonts/invoice-fonts/*').forEach(function(path) { + var fontName = /[^/]*$/.exec(path)[0], + files = {}, + license=''; + + // Add license text + grunt.file.expand({ filter: 'isFile'}, path+'/*.txt').forEach(function(path) { + var licenseText = grunt.file.read(path); + + // Fix anything that could escape from the comment + licenseText = licenseText.replace(/\*\//g,'*\\/'); + + license += "/*\n"+licenseText+"\n*/"; + }); + + // Create files list + files['public/js/vfs_fonts/'+fontName+'.js'] = [path+'/*.ttf']; + + out[fontName] = { + options: { + pre: license+'window.ninjaFontVfs=window.ninjaFontVfs||{};window.ninjaFontVfs.'+fontName+'=', + rootPath: path+'/' + }, + files: files + }; + }); + + // Return the computed object + return out; + }()), + concat: { + options: { + process: function(src, filepath) { + var basepath = filepath.substring(7, filepath.lastIndexOf('/') + 1); + // Fix relative paths for css files + if(filepath.indexOf('.css', filepath.length - 4) !== -1) { + return src.replace(/(url\s*[\("']+)\s*([^'"\)]+)(['"\)]+;?)/gi, function(match, start, url, end, offset, string) { + if(url.indexOf('data:') === 0) { + // Skip data urls + return match; + + } else if(url.indexOf('/') === 0) { + // Skip absolute urls + return match; + + } else { + return start + basepath + url + end; + } + }); + + // Fix source maps locations + } else if(filepath.indexOf('.js', filepath.length - 4) !== -1) { + return src.replace(/(\/[*\/][#@]\s*sourceMappingURL=)([^\s]+)/gi, function(match, start, url, offset, string) { + if(url.indexOf('/') === 0) { + // Skip absolute urls + return match; + + } else { + return start + basepath + url; + } + }); + + // Don't do anything for unknown file types + } else { + return src; + } + }, + }, + js: { + src: [ + 'public/vendor/jquery/dist/jquery.js', + 'public/vendor/jquery-ui/jquery-ui.min.js', + 'public/vendor/bootstrap/dist/js/bootstrap.min.js', + 'public/vendor/datatables/media/js/jquery.dataTables.js', + 'public/vendor/datatables-bootstrap3/BS3/assets/js/datatables.js', + 'public/vendor/knockout.js/knockout.js', + 'public/vendor/knockout-mapping/build/output/knockout.mapping-latest.js', + 'public/vendor/knockout-sortable/build/knockout-sortable.min.js', + 'public/vendor/underscore/underscore.js', + 'public/vendor/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.de.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.da.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.pt-BR.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.nl.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fr.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.it.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.lt.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.no.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.es.min.js', + 'public/vendor/bootstrap-datepicker/dist/locales/bootstrap-datepicker.sv.min.js', + 'public/vendor/dropzone/dist/min/dropzone.min.js', + 'public/vendor/typeahead.js/dist/typeahead.jquery.min.js', + 'public/vendor/accounting/accounting.min.js', + 'public/vendor/spectrum/spectrum.js', + 'public/vendor/jspdf/dist/jspdf.min.js', + 'public/vendor/moment/min/moment.min.js', + 'public/vendor/moment-timezone/builds/moment-timezone-with-data.min.js', + 'public/vendor/stacktrace-js/dist/stacktrace-with-polyfills.min.js', + 'public/vendor/fuse.js/src/fuse.min.js', + //'public/vendor/moment-duration-format/lib/moment-duration-format.js', + //'public/vendor/handsontable/dist/jquery.handsontable.full.min.js', + //'public/vendor/pdfmake/build/pdfmake.min.js', + //'public/vendor/pdfmake/build/vfs_fonts.js', + //'public/js/vfs_fonts.js', + 'public/js/bootstrap-combobox.js', + 'public/js/script.js', + 'public/js/pdf.pdfmake.js', + ], + dest: 'public/built.js', + nonull: true + }, + js_public: { + src: [ + /* + 'public/js/simpleexpand.js', + 'public/js/valign.js', + 'public/js/bootstrap.min.js', + 'public/js/simpleexpand.js', + */ + 'public/vendor/bootstrap/dist/js/bootstrap.min.js', + 'public/js/bootstrap-combobox.js', + + ], + dest: 'public/built.public.js', + nonull: true + }, + css: { + src: [ + 'public/vendor/bootstrap/dist/css/bootstrap.min.css', + 'public/vendor/datatables/media/css/jquery.dataTables.css', + 'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css', + 'public/vendor/font-awesome/css/font-awesome.min.css', + 'public/vendor/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css', + 'public/vendor/dropzone/dist/min/dropzone.min.css', + 'public/vendor/spectrum/spectrum.css', + 'public/css/bootstrap-combobox.css', + 'public/css/typeahead.js-bootstrap.css', + //'public/vendor/handsontable/dist/jquery.handsontable.full.css', + 'public/css/style.css', + ], + dest: 'public/css/built.css', + nonull: true, + options: { + process: false + } + }, + css_public: { + src: [ + 'public/vendor/bootstrap/dist/css/bootstrap.min.css', + 'public/vendor/font-awesome/css/font-awesome.min.css', + 'public/css/bootstrap-combobox.css', + 'public/vendor/datatables/media/css/jquery.dataTables.css', + 'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css', + 'public/css/public.style.css', + ], + dest: 'public/css/built.public.css', + nonull: true, + options: { + process: false + } + }, + js_pdf: { + src: [ + 'public/js/pdf_viewer.js', + 'public/js/compatibility.js', + 'public/js/pdfmake.min.js', + 'public/js/vfs.js', + ], + dest: 'public/pdf.built.js', + nonull: true + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-dump-dir'); + + grunt.registerTask('default', ['dump_dir', 'concat']); + +}; diff --git a/README.md b/README.md index f772df098023..e2bc81e2b63c 100644 --- a/README.md +++ b/README.md @@ -74,4 +74,4 @@ For information on how contribute to Invoice Ninja, please see our [contributing ## License Invoice Ninja is released under the Attribution Assurance License. -See [LICENSE](LICENSE) for details. +See [LICENSE](LICENSE) for details. \ No newline at end of file diff --git a/app/Commands/Command.php b/app/Commands/Command.php index e0be76979932..d6a8d61150ae 100644 --- a/app/Commands/Command.php +++ b/app/Commands/Command.php @@ -1,10 +1,5 @@ -client->public_id); - if ( ! $account) { - continue; - } $company = $account->company; if ( ! $company->plan || $company->plan == PLAN_FREE) { continue; diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index d2afce01cec5..567c6972489c 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -1,6 +1,4 @@ -info("=== Client:{$client->id} Balance:{$client->balance} Actual Balance:{$client->actual_balance} ==="); + $foundProblem = false; $lastBalance = 0; $lastAdjustment = 0; $lastCreatedAt = null; @@ -183,16 +182,8 @@ class CheckData extends Command { $activities = DB::table('activities') ->where('client_id', '=', $client->id) ->orderBy('activities.id') - ->get( - [ - 'activities.id', - 'activities.created_at', - 'activities.activity_type_id', - 'activities.adjustment', - 'activities.balance', - 'activities.invoice_id' - ] - ); + ->get(['activities.id', 'activities.created_at', 'activities.activity_type_id', 'activities.adjustment', 'activities.balance', 'activities.invoice_id']); + //$this->info(var_dump($activities)); foreach ($activities as $activity) { @@ -240,11 +231,13 @@ class CheckData extends Command { // **Fix for allowing converting a recurring invoice to a normal one without updating the balance** if ($noAdjustment && $invoice->invoice_type_id == INVOICE_TYPE_STANDARD && !$invoice->is_recurring) { $this->info("No adjustment for new invoice:{$activity->invoice_id} amount:{$invoice->amount} invoiceTypeId:{$invoice->invoice_type_id} isRecurring:{$invoice->is_recurring}"); + $foundProblem = true; $clientFix += $invoice->amount; $activityFix = $invoice->amount; // **Fix for updating balance when creating a quote or recurring invoice** } elseif ($activity->adjustment != 0 && ($invoice->invoice_type_id == INVOICE_TYPE_QUOTE || $invoice->is_recurring)) { $this->info("Incorrect adjustment for new invoice:{$activity->invoice_id} adjustment:{$activity->adjustment} invoiceTypeId:{$invoice->invoice_type_id} isRecurring:{$invoice->is_recurring}"); + $foundProblem = true; $clientFix -= $activity->adjustment; $activityFix = 0; } @@ -252,6 +245,7 @@ class CheckData extends Command { // **Fix for updating balance when deleting a recurring invoice** if ($activity->adjustment != 0 && $invoice->is_recurring) { $this->info("Incorrect adjustment for deleted invoice adjustment:{$activity->adjustment}"); + $foundProblem = true; if ($activity->balance != $lastBalance) { $clientFix -= $activity->adjustment; } @@ -261,6 +255,7 @@ class CheckData extends Command { // **Fix for updating balance when archiving an invoice** if ($activity->adjustment != 0 && !$invoice->is_recurring) { $this->info("Incorrect adjustment for archiving invoice adjustment:{$activity->adjustment}"); + $foundProblem = true; $activityFix = 0; $clientFix += $activity->adjustment; } @@ -268,10 +263,12 @@ class CheckData extends Command { // **Fix for updating balance when updating recurring invoice** if ($activity->adjustment != 0 && $invoice->is_recurring) { $this->info("Incorrect adjustment for updated recurring invoice adjustment:{$activity->adjustment}"); + $foundProblem = true; $clientFix -= $activity->adjustment; $activityFix = 0; } else if ((strtotime($activity->created_at) - strtotime($lastCreatedAt) <= 1) && $activity->adjustment > 0 && $activity->adjustment == $lastAdjustment) { $this->info("Duplicate adjustment for updated invoice adjustment:{$activity->adjustment}"); + $foundProblem = true; $clientFix -= $activity->adjustment; $activityFix = 0; } @@ -279,6 +276,7 @@ class CheckData extends Command { // **Fix for updating balance when updating a quote** if ($activity->balance != $lastBalance) { $this->info("Incorrect adjustment for updated quote adjustment:{$activity->adjustment}"); + $foundProblem = true; $clientFix += $lastBalance - $activity->balance; $activityFix = 0; } @@ -286,6 +284,7 @@ class CheckData extends Command { // **Fix for deleting payment after deleting invoice** if ($activity->adjustment != 0 && $invoice->is_deleted && $activity->created_at > $invoice->deleted_at) { $this->info("Incorrect adjustment for deleted payment adjustment:{$activity->adjustment}"); + $foundProblem = true; $activityFix = 0; $clientFix -= $activity->adjustment; } diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php index f4364e5d0675..a75922635f75 100644 --- a/app/Console/Commands/CreateTestData.php +++ b/app/Console/Commands/CreateTestData.php @@ -1,8 +1,5 @@ - $invoice->id, @@ -171,9 +167,9 @@ class CreateTestData extends Command } /** - * @param Vendor $vendor + * @param $vendor */ - private function createExpense(Vendor $vendor) + private function createExpense($vendor) { for ($i=0; $i<$this->count; $i++) { $data = [ diff --git a/app/Console/Commands/GenerateResources.php b/app/Console/Commands/GenerateResources.php index 2766a906c1bd..9826f3c70b07 100644 --- a/app/Console/Commands/GenerateResources.php +++ b/app/Console/Commands/GenerateResources.php @@ -1,6 +1,4 @@ -comment(PHP_EOL . Inspiring::quote() . PHP_EOL); - } + /** + * The console command description. + * + * @var string + */ + protected $description = 'Display an inspiring quote'; + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $this->comment(PHP_EOL.Inspiring::quote().PHP_EOL); + } } diff --git a/app/Console/Commands/PruneData.php b/app/Console/Commands/PruneData.php index c7e3f834709a..1c04e1ab5fcf 100644 --- a/app/Console/Commands/PruneData.php +++ b/app/Console/Commands/PruneData.php @@ -1,6 +1,4 @@ -sendOutputTo($logFile) ->daily(); } - - // Reset the invoice schema counter at the turn of the year - $schedule - ->command('ninja:reset-invoice-schema-counter') - ->daily(); } } diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 324b7796a959..0eecaba698cb 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -16,17 +16,17 @@ use Illuminate\Validation\ValidationException; class Handler extends ExceptionHandler { - /** - * A list of the exception types that should not be reported. - * - * @var array - */ - protected $dontReport = [ + /** + * A list of the exception types that should not be reported. + * + * @var array + */ + protected $dontReport = [ AuthorizationException::class, HttpException::class, ModelNotFoundException::class, ValidationException::class, - ]; + ]; /** * Report or log an exception. @@ -36,14 +36,14 @@ class Handler extends ExceptionHandler * @param \Exception $e * @return bool|void */ - public function report(Exception $e) - { + public function report(Exception $e) + { // don't show these errors in the logs if ($e instanceof HttpResponseException) { return false; } - - if (Utils::isNinja() && !Utils::isTravis()) { + + if (Utils::isNinja() && ! Utils::isTravis()) { Utils::logError(Utils::getErrorString($e)); return false; } else { @@ -51,16 +51,15 @@ class Handler extends ExceptionHandler } } - /** - * Render an exception into an HTTP response. - * - * @param \Illuminate\Http\Request $request - * @param \Exception $e - * - * @return \Illuminate\Http\Response - */ - public function render($request, Exception $e) - { + /** + * Render an exception into an HTTP response. + * + * @param \Illuminate\Http\Request $request + * @param \Exception $e + * @return \Illuminate\Http\Response + */ + public function render($request, Exception $e) + { if ($e instanceof ModelNotFoundException) { return Redirect::to('/'); } elseif ($e instanceof \Illuminate\Session\TokenMismatchException) { @@ -68,27 +67,26 @@ class Handler extends ExceptionHandler if ($request->path() != 'get_started') { // https://gist.github.com/jrmadsen67/bd0f9ad0ef1ed6bb594e return redirect() - ->back() - ->withInput($request->except('password', '_token')) - ->with([ - 'warning' => trans('texts.token_expired') - ]); + ->back() + ->withInput($request->except('password', '_token')) + ->with([ + 'warning' => trans('texts.token_expired') + ]); } } // In production, except for maintenance mode, we'll show a custom error screen if (Utils::isNinjaProd() && !Utils::isDownForMaintenance() - && !($e instanceof HttpResponseException) - ) { + && !($e instanceof HttpResponseException)) { $data = [ 'error' => get_class($e), 'hideHeader' => true, ]; - + return response()->view('error', $data); } else { return parent::render($request, $e); } - } + } } diff --git a/app/Handlers/InvoiceEventHandler.php b/app/Handlers/InvoiceEventHandler.php index 986cac7a08be..924a9590ee36 100644 --- a/app/Handlers/InvoiceEventHandler.php +++ b/app/Handlers/InvoiceEventHandler.php @@ -1,83 +1,51 @@ -userMailer = $userMailer; + $this->contactMailer = $contactMailer; + } - /** - * InvoiceEventHandler constructor. - * - * @param UserMailer $userMailer - * @param ContactMailer $contactMailer - */ - public function __construct(UserMailer $userMailer, ContactMailer $contactMailer) - { - $this->userMailer = $userMailer; - $this->contactMailer = $contactMailer; - } + public function subscribe($events) + { + $events->listen('invoice.sent', 'InvoiceEventHandler@onSent'); + $events->listen('invoice.viewed', 'InvoiceEventHandler@onViewed'); + $events->listen('invoice.paid', 'InvoiceEventHandler@onPaid'); + } - /** - * @param $events - */ - public function subscribe($events) - { - $events->listen('invoice.sent', 'InvoiceEventHandler@onSent'); - $events->listen('invoice.viewed', 'InvoiceEventHandler@onViewed'); - $events->listen('invoice.paid', 'InvoiceEventHandler@onPaid'); - } + public function onSent($invoice) + { + $this->sendNotifications($invoice, 'sent'); + } - /** - * @param Invoice $invoice - */ - public function onSent(Invoice $invoice) - { - $this->sendNotifications($invoice, 'sent'); - } + public function onViewed($invoice) + { + $this->sendNotifications($invoice, 'viewed'); + } - /** - * @param Invoice $invoice - */ - public function onViewed(Invoice $invoice) - { - $this->sendNotifications($invoice, 'viewed'); - } + public function onPaid($payment) + { + $this->contactMailer->sendPaymentConfirmation($payment); - /** - * @param Payment $payment - */ - public function onPaid(Payment $payment) - { - $this->contactMailer->sendPaymentConfirmation($payment); + $this->sendNotifications($payment->invoice, 'paid', $payment); + } - $this->sendNotifications($payment->invoice, 'paid', $payment); - } - - /** - * @param Invoice $invoice - * @param $type - * @param null $payment - */ - private function sendNotifications(Invoice $invoice, $type, $payment = null) - { - foreach ($invoice->account->users as $user) { - if ($user->{'notify_' . $type}) { + private function sendNotifications($invoice, $type, $payment = null) + { + foreach ($invoice->account->users as $user) + { + if ($user->{'notify_' . $type}) + { $this->userMailer->sendNotification($user, $invoice, $type, $payment); - } - } - } + } + } + } } \ No newline at end of file diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 34890a48e1e3..b1bc186d9f84 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -1461,6 +1461,7 @@ class AccountController extends BaseController return trans('texts.create_invoice_for_sample'); } + /** @var \App\Models\Account $account */ $account = Auth::user()->account; $invitation = $invoice->invitations->first(); diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index 5d432881d261..1a3db4b8d7cf 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -62,7 +62,7 @@ class CreditController extends BaseController 'method' => 'POST', 'url' => 'credits', 'title' => trans('texts.new_credit'), - 'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), + 'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), ]; return View::make('credits.edit', $data); diff --git a/app/Http/Controllers/DocumentController.php b/app/Http/Controllers/DocumentController.php index 4bb93432fa20..f25a027f8662 100644 --- a/app/Http/Controllers/DocumentController.php +++ b/app/Http/Controllers/DocumentController.php @@ -1,6 +1,5 @@ documentRepo->upload($request->all(), $doc_array); if(is_string($result)){ diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 7c4df9d3d6f6..3447e81f538d 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -1,13 +1,11 @@ -registered; } - /** - * @return bool - */ public static function isConfirmed() { return Auth::check() && Auth::user()->confirmed; } - /** - * @return bool - */ public static function isDatabaseSetup() { try { @@ -59,89 +44,59 @@ class Utils } } - /** - * @return bool - */ public static function isDownForMaintenance() { return file_exists(storage_path() . '/framework/down'); } - /** - * @return bool - */ public static function isCron() { return php_sapi_name() == 'cli'; } - /** - * @return bool - */ public static function isTravis() { return env('TRAVIS') == 'true'; } - /** - * @return bool - */ public static function isNinja() { return self::isNinjaProd() || self::isNinjaDev(); } - /** - * @return bool - */ public static function isNinjaProd() { - if (static::isReseller()) { + if (Utils::isReseller()) { return true; } return env('NINJA_PROD') == 'true'; } - /** - * @return bool - */ public static function isNinjaDev() { return env('NINJA_DEV') == 'true'; } - /** - * @return bool - */ public static function requireHTTPS() { - if (app('request')->root() === 'http://ninja.dev' || app('request')->root() === 'http://ninja.dev:8000') { + if (Request::root() === 'http://ninja.dev' || Request::root() === 'http://ninja.dev:8000') { return false; } - return static::isNinjaProd() || env('REQUIRE_HTTPS'); + return Utils::isNinjaProd() || (isset($_ENV['REQUIRE_HTTPS']) && $_ENV['REQUIRE_HTTPS'] == 'true'); } - /** - * @return bool - */ public static function isReseller() { - return self::getResellerType() ? true : false; + return Utils::getResllerType() ? true : false; } - /** - * @return array|bool - */ - public static function getResellerType() + public static function getResllerType() { return isset($_ENV['RESELLER_TYPE']) ? $_ENV['RESELLER_TYPE'] : false; } - /** - * @return bool - */ public static function isOAuthEnabled() { $providers = [ @@ -161,80 +116,46 @@ class Utils return false; } - /** - * @return bool - */ public static function allowNewAccounts() { - return static::isNinja() || Auth::check(); + return Utils::isNinja() || Auth::check(); } - /** - * @return bool - */ public static function isPro() { return Auth::check() && Auth::user()->isPro(); } - /** - * @param $feature - * - * @return bool - */ public static function hasFeature($feature) { return Auth::check() && Auth::user()->hasFeature($feature); } - /** - * @return bool - */ public static function isAdmin() { return Auth::check() && Auth::user()->is_admin; } - /** - * @param $permission - * @param bool $requireAll - * - * @return bool - */ public static function hasPermission($permission, $requireAll = false) { return Auth::check() && Auth::user()->hasPermission($permission, $requireAll); } - /** - * @param $permission - * - * @return bool - */ public static function hasAllPermissions($permission) { return Auth::check() && Auth::user()->hasPermission($permission); } - /** - * @return bool - */ public static function isTrial() { return Auth::check() && Auth::user()->isTrial(); } - /** - * @return bool - */ public static function isEnglish() { return App::getLocale() == 'en'; } - /** - * @return string - */ public static function getLocaleRegion() { $parts = explode('_', App::getLocale()); @@ -242,21 +163,15 @@ class Utils return count($parts) ? $parts[0] : 'en'; } - /** - * @return mixed - */ public static function getUserType() { - if (static::isNinja()) { + if (Utils::isNinja()) { return USER_TYPE_CLOUD_HOST; + } else { + return USER_TYPE_SELF_HOST; } - - return USER_TYPE_SELF_HOST; } - /** - * @return array|bool - */ public static function getDemoAccountId() { return isset($_ENV[DEMO_ACCOUNT_ID]) ? $_ENV[DEMO_ACCOUNT_ID] : false; @@ -265,7 +180,7 @@ class Utils public static function getNewsFeedResponse($userType = false) { if (!$userType) { - $userType = static::getUserType(); + $userType = Utils::getUserType(); } $response = new stdClass(); @@ -276,9 +191,6 @@ class Utils return $response; } - /** - * @return string - */ public static function getLastURL() { if (!count(Session::get(RECENTLY_VIEWED))) { @@ -289,31 +201,21 @@ class Utils $last = $history[0]; $penultimate = count($history) > 1 ? $history[1] : $last; - return app('request')->url() == $last->url ? $penultimate->url : $last->url; + return Request::url() == $last->url ? $penultimate->url : $last->url; } - /** - * @param $feature - * - * @return string - */ public static function getProLabel($feature) { if (Auth::check() && !Auth::user()->isPro() && $feature == ACCOUNT_ADVANCED_SETTINGS) { return ' PRO'; + } else { + return ''; } - - return ''; } - /** - * @param array $plan - * - * @return int - */ - public static function getPlanPrice(array $plan) + public static function getPlanPrice($plan) { $term = $plan['term']; $numUsers = $plan['num_users']; @@ -342,11 +244,6 @@ class Utils return $price; } - /** - * @param $max - * - * @return int - */ public static function getMinNumUsers($max) { if ($max <= 2) { @@ -358,19 +255,11 @@ class Utils } } - /** - * @return string - */ public static function basePath() { return substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/') + 1); } - /** - * @param $input - * - * @return array - */ public static function trans($input) { $data = []; @@ -388,12 +277,6 @@ class Utils return $data; } - /** - * @param bool $message - * @param bool $exception - * - * @return $this - */ public static function fatalError($message = false, $exception = false) { if (!$message) { @@ -410,11 +293,6 @@ class Utils return View::make('error', $data)->with('error', $message); } - /** - * @param $exception - * - * @return string - */ public static function getErrorString($exception) { $class = get_class($exception); @@ -422,13 +300,6 @@ class Utils return "***{$class}*** [{$code}] : {$exception->getFile()} [Line {$exception->getLine()}] => {$exception->getMessage()}"; } - /** - * @param $error - * @param string $context - * @param bool $info - * - * @return string - */ public static function logError($error, $context = 'PHP', $info = false) { if ($error instanceof Exception) { @@ -446,10 +317,10 @@ class Utils 'user_id' => Auth::check() ? Auth::user()->id : 0, 'account_id' => Auth::check() ? Auth::user()->account_id : 0, 'user_name' => Auth::check() ? Auth::user()->getDisplayName() : '', - 'method' => app('request')->method(), - 'url' => Input::get('url', app('request')->url()), + 'method' => Request::method(), + 'url' => Input::get('url', Request::url()), 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '', - 'ip' => app('request')->getClientIp(), + 'ip' => Request::getClientIp(), 'count' => Session::get('error_count', 0), ]; @@ -458,13 +329,15 @@ class Utils } else { Log::error($error."\n", $data); } + + /* + Mail::queue('emails.error', ['message'=>$error.' '.json_encode($data)], function($message) + { + $message->to($email)->subject($subject); + }); + */ } - /** - * @param $value - * - * @return float - */ public static function parseFloat($value) { $value = preg_replace('/[^0-9\.\-]/', '', $value); @@ -472,11 +345,6 @@ class Utils return floatval($value); } - /** - * @param $value - * - * @return int - */ public static function parseInt($value) { $value = preg_replace('/[^0-9]/', '', $value); @@ -484,12 +352,6 @@ class Utils return intval($value); } - /** - * @param $id - * @param $type - * - * @return null - */ public static function getFromCache($id, $type) { $cache = Cache::get($type); @@ -498,19 +360,13 @@ class Utils return null; } - return $cache->filter(function($item) use ($id) { + $data = $cache->filter(function($item) use ($id) { return $item->id == $id; - })->first(); + }); + + return $data->first(); } - /** - * @param $value - * @param bool $currencyId - * @param bool $countryId - * @param bool $showCode - * - * @return string - */ public static function formatMoney($value, $currencyId = false, $countryId = false, $showCode = false) { if (!$value) { @@ -555,12 +411,6 @@ class Utils } } - /** - * @param $string - * @param $count - * - * @return mixed - */ public static function pluralize($string, $count) { $field = $count == 1 ? $string : $string.'s'; @@ -569,11 +419,6 @@ class Utils return $string; } - /** - * @param $type - * - * @return string - */ public static function pluralizeEntityType($type) { if ($type === ENTITY_EXPENSE_CATEGORY) { @@ -583,11 +428,6 @@ class Utils } } - /** - * @param $value - * - * @return string - */ public static function maskAccountNumber($value) { $length = strlen($value); @@ -599,13 +439,7 @@ class Utils return str_repeat('*', $length - 4) . $lastDigits; } - /** - * http://wephp.co/detect-credit-card-type-php/ - * - * @param $number - * - * @return string - */ + // http://wephp.co/detect-credit-card-type-php/ public static function getCardType($number) { $number = preg_replace('/[^\d]/', '', $number); @@ -622,92 +456,52 @@ class Utils return 'MasterCard'; } elseif (preg_match('/^4[0-9]{12}(?:[0-9]{3})?$/', $number)) { return 'Visa'; + } else { + return 'Unknown'; } - - return 'Unknown'; } - /** - * @param $data - * - * @return mixed - */ public static function toArray($data) { return json_decode(json_encode((array) $data), true); } - /** - * @param $string - * - * @return mixed - */ public static function toSpaceCase($string) { return preg_replace('/([a-z])([A-Z])/s', '$1 $2', $string); } - /** - * @param $string - * - * @return mixed - */ public static function toSnakeCase($string) { return preg_replace('/([a-z])([A-Z])/s', '$1_$2', $string); } - /** - * @param $string - * - * @return string - */ public static function toCamelCase($string) { return lcfirst(static::toClassCase($string)); } - /** - * @param $string - * - * @return mixed - */ public static function toClassCase($string) { return str_replace(' ', '', ucwords(str_replace('_', ' ', $string))); } - /** - * @param $timestamp - * - * @return string - */ public static function timestampToDateTimeString($timestamp) { $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE); $format = Session::get(SESSION_DATETIME_FORMAT, DEFAULT_DATETIME_FORMAT); - return self::timestampToString($timestamp, $timezone, $format); + return Utils::timestampToString($timestamp, $timezone, $format); } - /** - * @param $timestamp - * - * @return string - */ public static function timestampToDateString($timestamp) { $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE); $format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT); - return self::timestampToString($timestamp, $timezone, $format); + return Utils::timestampToString($timestamp, $timezone, $format); } - /** - * @param $date - * - * @return bool|string - */ public static function dateToString($date) { if (!$date) { @@ -723,16 +517,9 @@ class Utils $timestamp = $dateTime->getTimestamp(); $format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT); - return static::timestampToString($timestamp, false, $format); + return Utils::timestampToString($timestamp, false, $format); } - /** - * @param $timestamp - * @param bool $timezone - * @param $format - * - * @return string - */ public static function timestampToString($timestamp, $timezone = false, $format) { if (!$timestamp) { @@ -749,12 +536,6 @@ class Utils return $date->format($format); } - /** - * @param $date - * @param bool $formatResult - * - * @return DateTime|string|void - */ public static function toSqlDate($date, $formatResult = true) { if (!$date) { @@ -770,12 +551,6 @@ class Utils return $formatResult ? $dateTime->format('Y-m-d') : $dateTime; } - /** - * @param $date - * @param bool $formatResult - * - * @return DateTime|string - */ public static function fromSqlDate($date, $formatResult = true) { if (!$date || $date == '0000-00-00') { @@ -791,12 +566,6 @@ class Utils return $formatResult ? $dateTime->format($format) : $dateTime; } - /** - * @param $date - * @param bool $formatResult - * - * @return DateTime|string - */ public static function fromSqlDateTime($date, $formatResult = true) { if (!$date || $date == '0000-00-00 00:00:00') { @@ -812,23 +581,13 @@ class Utils return $formatResult ? $dateTime->format($format) : $dateTime; } - /** - * @param $time - * - * @return mixed - */ - public static function formatTime($time) + public static function formatTime($t) { // http://stackoverflow.com/a/3172665 $f = ':'; - return sprintf('%02d%s%02d%s%02d', floor($time/3600), $f, ($time/60)%60, $f, $time%60); + return sprintf('%02d%s%02d%s%02d', floor($t/3600), $f, ($t/60)%60, $f, $t%60); } - /** - * @param bool $formatResult - * - * @return mixed - */ public static function today($formatResult = true) { $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE); @@ -843,15 +602,10 @@ class Utils } } - /** - * @param $name - * @param $type - * @param bool $url - */ public static function trackViewed($name, $type, $url = false) { if (!$url) { - $url = app('request')->url(); + $url = Request::url(); } $viewed = Session::get(RECENTLY_VIEWED); @@ -893,11 +647,6 @@ class Utils Session::put(RECENTLY_VIEWED, $data); } - /** - * @param $str - * - * @return mixed|string - */ public static function processVariables($str) { if (!$str) { @@ -926,7 +675,7 @@ class Utils $offset = intval($minArray[1]) * -1; } - $val = self::getDatePart($variable, $offset); + $val = Utils::getDatePart($variable, $offset); $str = str_replace($match, $val, $str); } } @@ -934,29 +683,18 @@ class Utils return $str; } - /** - * @param $part - * @param $offset - * - * @return int|string|\Symfony\Component\Translation\TranslatorInterface - */ private static function getDatePart($part, $offset) { $offset = intval($offset); if ($part == 'MONTH') { - return self::getMonth($offset); + return Utils::getMonth($offset); } elseif ($part == 'QUARTER') { - return self::getQuarter($offset); + return Utils::getQuarter($offset); } elseif ($part == 'YEAR') { - return self::getYear($offset); + return Utils::getYear($offset); } } - /** - * @param $offset - * - * @return string|\Symfony\Component\Translation\TranslatorInterface - */ private static function getMonth($offset) { $months = ['january', 'february', 'march', 'april', 'may', 'june', @@ -974,11 +712,6 @@ class Utils return trans('texts.' . $months[$month]); } - /** - * @param $offset - * - * @return string - */ private static function getQuarter($offset) { $month = intval(date('n')) - 1; @@ -992,11 +725,6 @@ class Utils return 'Q'.$quarter; } - /** - * @param $offset - * - * @return int - */ private static function getYear($offset) { $year = intval(date('Y')); @@ -1004,31 +732,16 @@ class Utils return $year + $offset; } - /** - * @param $entityType - * - * @return string - */ public static function getEntityClass($entityType) { return 'App\\Models\\' . static::getEntityName($entityType); } - /** - * @param $entityType - * - * @return string - */ public static function getEntityName($entityType) { - return ucwords(static::toCamelCase($entityType)); + return ucwords(Utils::toCamelCase($entityType)); } - /** - * @param $model - * - * @return string - */ public static function getClientDisplayName($model) { if ($model->client_name) { @@ -1040,31 +753,17 @@ class Utils } } - /** - * @param $model - * - * @return string - */ public static function getVendorDisplayName($model) { - if(is_null($model)) { + if(is_null($model)) return ''; - } - if($model->vendor_name) { + if($model->vendor_name) return $model->vendor_name; - } return 'No vendor name'; } - /** - * @param $firstName - * @param $lastName - * @param $email - * - * @return string - */ public static function getPersonDisplayName($firstName, $lastName, $email) { if ($firstName || $lastName) { @@ -1076,9 +775,6 @@ class Utils } } - /** - * @return mixed - */ public static function generateLicense() { $parts = []; @@ -1089,11 +785,6 @@ class Utils return implode('-', $parts); } - /** - * @param string $eventName - * - * @return bool - */ public static function lookupEventId($eventName) { if ($eventName == 'create_client') { @@ -1106,15 +797,11 @@ class Utils return EVENT_CREATE_PAYMENT; } elseif ($eventName == 'create_vendor') { return EVENT_CREATE_VENDOR; + } else { + return false; } - - return false; } - /** - * @param $subscription - * @param $data - */ public static function notifyZapier($subscription, $data) { $curl = curl_init(); @@ -1131,6 +818,7 @@ class Utils curl_setopt_array($curl, $opts); + $result = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); @@ -1140,57 +828,37 @@ class Utils } } - /** - * @param int $count - * - * @return array - */ public static function getApiHeaders($count = 0) { return [ 'Content-Type' => 'application/json', + //'Access-Control-Allow-Origin' => '*', + //'Access-Control-Allow-Methods' => 'GET', + //'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With', + //'Access-Control-Allow-Credentials' => 'true', 'X-Total-Count' => $count, 'X-Ninja-Version' => NINJA_VERSION, + //'X-Rate-Limit-Limit' - The number of allowed requests in the current period + //'X-Rate-Limit-Remaining' - The number of remaining requests in the current period + //'X-Rate-Limit-Reset' - The number of seconds left in the current period, ]; } - /** - * @param $value - * - * @return bool - */ public static function isEmpty($value) { return !$value || $value == '0' || $value == '0.00' || $value == '0,00'; } - /** - * @param $haystack - * @param $needle - * - * @return bool - */ public static function startsWith($haystack, $needle) { return $needle === '' || strpos($haystack, $needle) === 0; } - /** - * @param $haystack - * @param $needle - * - * @return bool - */ public static function endsWith($haystack, $needle) { return $needle === '' || substr($haystack, -strlen($needle)) === $needle; } - /** - * @param $model - * - * @return string - */ public static function getEntityRowClass($model) { $str = ''; @@ -1210,11 +878,6 @@ class Utils return $str; } - /** - * @param $output - * @param $data - * @param bool $headers - */ public static function exportData($output, $data, $headers = false) { if ($headers) { @@ -1230,23 +893,26 @@ class Utils fwrite($output, "\n"); } - /** - * @param $values - * - * @return bool|mixed - */ public static function getFirst($values) { if (is_array($values)) { return count($values) ? $values[0] : false; + } else { + return $values; } - - return $values; } - /** - * @return string - */ + // nouns in German and French should be uppercase + // TODO remove this + public static function transFlowText($key) + { + $str = trans("texts.$key"); + if (!in_array(App::getLocale(), ['de', 'fr'])) { + $str = strtolower($str); + } + return $str; + } + public static function getSubdomainPlaceholder() { $parts = parse_url(SITE_URL); @@ -1260,9 +926,6 @@ class Utils return $subdomain; } - /** - * @return string - */ public static function getDomainPlaceholder() { $parts = parse_url(SITE_URL); @@ -1282,12 +945,6 @@ class Utils return $domain; } - /** - * @param string $domain - * @param $subdomain - * - * @return mixed - */ public static function replaceSubdomain($domain, $subdomain) { $parsedUrl = parse_url($domain); @@ -1299,11 +956,6 @@ class Utils return $domain; } - /** - * @param string $name - * - * @return array - */ public static function splitName($name) { $name = trim($name); @@ -1312,25 +964,12 @@ class Utils return [$firstName, $lastName]; } - /** - * @param string $string - * - * @return string - */ public static function decodePDF($string) { $string = str_replace('data:application/pdf;base64,', '', $string); return base64_decode($string); } - /** - * @param $city - * @param $state - * @param $postalCode - * @param $swap - * - * @return string - */ public static function cityStateZip($city, $state, $postalCode, $swap) { $str = $city; @@ -1344,16 +983,11 @@ class Utils if ($swap) { return $postalCode . ' ' . $str; + } else { + return $str . ' ' . $postalCode; } - - return $str . ' ' . $postalCode; } - /** - * @param $website - * - * @return string - */ public static function formatWebsite($website) { if (!$website) { @@ -1373,26 +1007,13 @@ class Utils return link_to($link, $title, ['target' => '_blank']); } - /** - * @param $adjustment - * @param $currencyId - * @param $countryId - * - * @return string - */ public static function wrapAdjustment($adjustment, $currencyId, $countryId) { $class = $adjustment <= 0 ? 'success' : 'default'; - $adjustment = self::formatMoney($adjustment, $currencyId, $countryId); + $adjustment = Utils::formatMoney($adjustment, $currencyId, $countryId); return "
t |
p,v=i.minHeight&&i.minHeight>f;i.grid=c,b&&(p+=l),v&&(f+=u),g&&(p-=l),m&&(f-=u),/^(se|s|e)$/.test(a)?(n.size.width=p,n.size.height=f):/^(ne)$/.test(a)?(n.size.width=p,n.size.height=f,n.position.top=s.top-d):/^(sw)$/.test(a)?(n.size.width=p,n.size.height=f,n.position.left=s.left-h):((f-u<=0||p-l<=0)&&(e=n._getPaddingPlusBorderDimensions(this)),f-u>0?(n.size.height=f,n.position.top=s.top-d):(f=u-e.height,n.size.height=f,n.position.top=s.top+r.height-f),p-l>0?(n.size.width=p,n.position.left=s.left-h):(p=u-e.height,n.size.width=p,n.position.left=s.left+r.width-p))}});t.ui.resizable,t.widget("ui.dialog",{version:"1.11.2",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"Close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var n=t(this).css(e).offset().top;n<0&&t(this).css("top",e.top-n)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var n,i=this;if(this._isOpen&&this._trigger("beforeClose",e)!==!1){if(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),!this.opener.filter(":focusable").focus().length)try{n=this.document[0].activeElement,n&&"body"!==n.nodeName.toLowerCase()&&t(n).blur()}catch(o){}this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,n){var i=!1,o=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),r=Math.max.apply(null,o);return r>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",r+1),i=!0),i&&!n&&this._trigger("focus",e),i},open:function(){var e=this;return this._isOpen?void(this._moveToTop()&&this._focusTabbable()):(this._isOpen=!0,this.opener=t(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),void this._trigger("open"))},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).focus()},_keepFocus:function(e){function n(){var e=this.document[0].activeElement,n=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);n||this._focusTabbable()}e.preventDefault(),n.call(this),this._delay(n)},_createWrapper:function(){this.uiDialog=t("
1&&M.splice.apply(M,[1,0].concat(M.splice(y,f+1))),s.dequeue()},t.effects.effect.clip=function(e,n){var i,o,r,s=t(this),a=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(s,e.mode||"hide"),l="show"===c,u=e.direction||"vertical",h="vertical"===u,d=h?"height":"width",p=h?"top":"left",f={};t.effects.save(s,a),s.show(),i=t.effects.createWrapper(s).css({overflow:"hidden"}),o="IMG"===s[0].tagName?i:s,r=o[d](),l&&(o.css(d,0),o.css(p,r/2)),f[d]=l?r:0,f[p]=l?0:r/2,o.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){l||s.hide(),t.effects.restore(s,a),t.effects.removeWrapper(s),n()}})},t.effects.effect.drop=function(e,n){var i,o=t(this),r=["position","top","bottom","left","right","opacity","height","width"],s=t.effects.setMode(o,e.mode||"hide"),a="show"===s,c=e.direction||"left",l="up"===c||"down"===c?"top":"left",u="up"===c||"left"===c?"pos":"neg",h={opacity:a?1:0};t.effects.save(o,r),o.show(),t.effects.createWrapper(o),i=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0)/2,a&&o.css("opacity",0).css(l,"pos"===u?-i:i),h[l]=(a?"pos"===u?"+=":"-=":"pos"===u?"-=":"+=")+i,o.animate(h,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===s&&o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),n()}})},t.effects.effect.explode=function(e,n){function i(){M.push(this),M.length===h*d&&o()}function o(){p.css({visibility:"visible"}),t(M).remove(),g||p.hide(),n()}var r,s,a,c,l,u,h=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=h,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),g="show"===f,m=p.show().css("visibility","hidden").offset(),b=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/h),M=[];for(r=0;r
t<"F"ip>'),x.renderer?i.isPlainObject(x.renderer)&&!x.renderer.header&&(x.renderer.header="jqueryui"):x.renderer="jqueryui"):i.extend(C,Vt.ext.classes,g.oClasses),i(this).addClass(C.sTable),""===x.oScroll.sX&&""===x.oScroll.sY||(x.oScroll.iBarWidth=Tt()),x.oScroll.sX===!0&&(x.oScroll.sX="100%"),x.iInitDisplayStart===n&&(x.iInitDisplayStart=g.iDisplayStart,x._iDisplayStart=g.iDisplayStart),null!==g.iDeferLoading){x.bDeferLoading=!0;var O=i.isArray(g.iDeferLoading);x._iRecordsDisplay=O?g.iDeferLoading[0]:g.iDeferLoading,x._iRecordsTotal=O?g.iDeferLoading[1]:g.iDeferLoading}var S=x.oLanguage;i.extend(!0,S,g.oLanguage),""!==S.sUrl&&(i.ajax({dataType:"json",url:S.sUrl,success:function(t){s(t),r(w.oLanguage,t),i.extend(!0,S,t),at(x)},error:function(){at(x)}}),v=!0),null===g.asStripeClasses&&(x.asStripeClasses=[C.sStripeOdd,C.sStripeEven]);var N=x.asStripeClasses,L=i("tbody tr:eq(0)",this);i.inArray(!0,i.map(N,function(t,e){return L.hasClass(t)}))!==-1&&(i("tbody tr",this).removeClass(N.join(" ")),x.asDestroyStripes=N.slice());var D,q=[],W=this.getElementsByTagName("thead");if(0!==W.length&&(X(x.aoHeader,W[0]),q=F(x)),null===g.aoColumns)for(D=[],m=0,p=q.length;m
").appendTo(this)),x.nTHead=P[0];var H=i(this).children("tbody");0===H.length&&(H=i("
").appendTo(this)),x.nTBody=H[0];var j=i(this).children("tfoot");if(0===j.length&&R.length>0&&(""!==x.oScroll.sX||""!==x.oScroll.sY)&&(j=i("").appendTo(this)),0===j.length||0===j.children().length?i(this).addClass(C.sNoFooter):j.length>0&&(x.nTFoot=j[0],X(x.aoFooter,x.nTFoot)),g.aaData)for(m=0;m