├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .htaccess ├── .travis.yml ├── Application.cfc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── box.json ├── config ├── app.cfm ├── development │ └── settings.cfm ├── environment.cfm ├── maintenance │ └── settings.cfm ├── production │ └── settings.cfm ├── routes.cfm ├── settings.cfm └── testing │ └── settings.cfm ├── controllers ├── Accounts.cfc ├── Controller.cfc ├── Main.cfc ├── PasswordResets.cfc ├── Register.cfc ├── Sessions.cfc ├── admin │ ├── Auditlogs.cfc │ ├── Permissions.cfc │ ├── Roles.cfc │ ├── Settings.cfc │ ├── UserPermissions.cfc │ └── Users.cfc └── functions │ ├── auth.cfm │ └── filters.cfm ├── events ├── onabort.cfm ├── onapplicationend.cfm ├── onapplicationstart.cfm ├── onerror.cfm ├── onmaintenance.cfm ├── onmissingtemplate.cfm ├── onrequestend.cfm ├── onrequeststart.cfm ├── onsessionend.cfm └── onsessionstart.cfm ├── files └── .keep ├── global ├── auth.cfm ├── functions.cfm ├── install.cfm ├── logging.cfm └── utils.cfm ├── images └── .keep ├── index.cfm ├── javascripts ├── .keep └── custom.js ├── migrator └── migrations │ ├── 20180519095317_Creates_User_Table.cfc │ ├── 20180519100056_Creates_Roles_Table.cfc │ ├── 20180519100244_Creates_Permissions_Table.cfc │ ├── 20180519100412_Creates_RolePermissions_Table.cfc │ ├── 20180519100428_Creates_UserPermissions_Table.cfc │ ├── 20180519100429_Creates_Settings_Table.cfc │ ├── 20180519100430_Creates_Auditlog_Table.cfc │ ├── 20180519105943_Adds_Default_Roles.cfc │ ├── 20180519105944_Adds_Default_UserAccounts.cfc │ ├── 20180519105945_Adds_Default_Settings.cfc │ ├── 20180519105946_Adds_Default_Permissions.cfc │ ├── 20180519105947_Adds_Default_UserPermissions.cfc │ └── 20180519105948_Adds_Dummy_Auditlogs.cfc ├── miscellaneous └── Application.cfc ├── models ├── Auditlog.cfc ├── Model.cfc ├── Permission.cfc ├── Role.cfc ├── RolePermission.cfc ├── Setting.cfc ├── User.cfc ├── UserPermission.cfc └── auth │ ├── LDAP.cfc │ └── Local.cfc ├── plugins ├── .keep ├── FlashMessagesBootstrap-1.0.2.zip ├── authenticateThis-1.0.1.zip └── jsconfirm-1.0.5.zip ├── rewrite.cfm ├── root.cfm ├── server-exampleappACF.json ├── server.json ├── stylesheets ├── .keep └── custom.css ├── tests ├── Test.cfc ├── functions │ ├── Auth.cfc │ ├── Permissions.cfc │ ├── Utils.cfc │ └── models │ │ ├── Auditlog.cfc │ │ ├── Permission.cfc │ │ ├── Role.cfc │ │ └── User.cfc └── requests │ ├── Accounts.cfc │ ├── Main.cfc │ └── Sessions.cfc ├── urlrewrite.xml ├── views ├── accounts │ ├── edit.cfm │ ├── resetPassword.cfm │ └── show.cfm ├── admin │ ├── auditlogs │ │ ├── _filter.cfm │ │ ├── _modal.cfm │ │ └── index.cfm │ ├── permissions │ │ ├── _form.cfm │ │ ├── edit.cfm │ │ └── index.cfm │ ├── roles │ │ ├── _form.cfm │ │ ├── edit.cfm │ │ ├── index.cfm │ │ └── new.cfm │ ├── settings │ │ ├── _form.cfm │ │ ├── edit.cfm │ │ └── index.cfm │ ├── userpermissions │ │ └── index.cfm │ └── users │ │ ├── _filter.cfm │ │ ├── edit.cfm │ │ ├── form │ │ ├── _auth.cfm │ │ ├── _details.cfm │ │ └── _role.cfm │ │ ├── index.cfm │ │ ├── new.cfm │ │ └── show.cfm ├── emails │ ├── _footer.cfm │ ├── _header.cfm │ ├── passwordReset.cfm │ ├── passwordResetAdmin.cfm │ ├── passwordResetAdminPlain.cfm │ ├── passwordResetPlain.cfm │ ├── verify.cfm │ └── verifyPlain.cfm ├── helpers.cfm ├── layout.cfm ├── layout │ ├── _footer.cfm │ └── _navigation.cfm ├── main │ └── index.cfm ├── passwordresets │ ├── edit.cfm │ └── new.cfm ├── register │ └── new.cfm ├── sessions │ └── new.cfm └── wheels │ ├── layout.cfm │ └── wheels.cfm └── wheels ├── CHANGELOG.md ├── Controller.cfc ├── Dispatch.cfc ├── LICENSE ├── Mapper.cfc ├── Migrator.cfc ├── Model.cfc ├── Plugins.cfc ├── Public.cfc ├── Test.cfc ├── controller ├── appfunctions.cfm ├── caching.cfm ├── csrf.cfm ├── filters.cfm ├── flash.cfm ├── functions.cfm ├── initialization.cfm ├── layouts.cfm ├── miscellaneous.cfm ├── processing.cfm ├── provides.cfm ├── redirection.cfm ├── rendering.cfm └── verifies.cfm ├── dispatch └── functions.cfm ├── events ├── onabort.cfm ├── onapplicationend.cfm ├── onapplicationstart.cfm ├── onerror.cfm ├── onerror │ ├── cfmlerror.cfm │ └── wheelserror.cfm ├── onmissingtemplate.cfm ├── onrequest.cfm ├── onrequestend.cfm ├── onrequestend │ └── debug.cfm ├── onrequeststart.cfm ├── onsessionend.cfm └── onsessionstart.cfm ├── functions.cfm ├── global ├── appfunctions.cfm ├── cfml.cfm ├── functions.cfm ├── internal.cfm ├── misc.cfm └── util.cfm ├── index.cfm ├── mapper ├── functions.cfm ├── initialization.cfm ├── mapping.cfm ├── matching.cfm ├── resources.cfm ├── scoping.cfm └── utilities.cfm ├── migrator ├── Base.cfc ├── ColumnDefinition.cfc ├── ForeignKeyDefinition.cfc ├── Migration.cfc ├── TableDefinition.cfc ├── ViewDefinition.cfc ├── adapters │ ├── Abstract.cfc │ ├── H2.cfc │ ├── MicrosoftSQLServer.cfc │ ├── MySQL.cfc │ └── PostgreSQL.cfc ├── basefunctions.cfm ├── functions.cfm └── templates │ ├── announce.cfc │ ├── blank.cfc │ ├── change-column.cfc │ ├── change-table.cfc │ ├── create-column.cfc │ ├── create-index.cfc │ ├── create-record.cfc │ ├── create-table.cfc │ ├── execute.cfc │ ├── remove-column.cfc │ ├── remove-index.cfc │ ├── remove-record.cfc │ ├── remove-table.cfc │ ├── rename-column.cfc │ ├── rename-table.cfc │ └── update-record.cfc ├── model ├── adapters │ ├── Base.cfc │ ├── H2.cfc │ ├── MySQL.cfc │ ├── Oracle.cfc │ ├── PostgreSQL.cfc │ ├── SQLServer.cfc │ └── cfquery.cfm ├── associations.cfm ├── calculations.cfm ├── callbacks.cfm ├── create.cfm ├── delete.cfm ├── errors.cfm ├── functions.cfm ├── initialization.cfm ├── miscellaneous.cfm ├── nestedproperties.cfm ├── onmissingmethod.cfm ├── properties.cfm ├── read.cfm ├── serialize.cfm ├── sql.cfm ├── transactions.cfm ├── update.cfm └── validations.cfm ├── plugins ├── functions.cfm ├── initialization.cfm └── standalone │ └── injection.cfm ├── public ├── README.md ├── assets │ ├── .gitignore │ └── semantic │ │ └── dist │ │ ├── semantic.min.css │ │ └── semantic.min.js ├── docs │ ├── core.cfm │ ├── layouts │ │ ├── html.cfm │ │ └── json.cfm │ └── reference │ │ ├── controller │ │ ├── addformat.txt │ │ ├── authenticitytokenfield.txt │ │ ├── autolink.txt │ │ ├── buttontag.txt │ │ ├── buttonto.txt │ │ ├── caches.txt │ │ ├── capitalize.txt │ │ ├── checkbox.txt │ │ ├── checkboxtag.txt │ │ ├── columndataforproperty.txt │ │ ├── columnforproperty.txt │ │ ├── columnnames.txt │ │ ├── columns.txt │ │ ├── compareto.txt │ │ ├── contentfor.txt │ │ ├── contentforlayout.txt │ │ ├── controller.txt │ │ ├── csrfmetatags.txt │ │ ├── cycle.txt │ │ ├── dateselect.txt │ │ ├── dateselecttags.txt │ │ ├── datetimeselect.txt │ │ ├── datetimeselecttags.txt │ │ ├── dayselecttag.txt │ │ ├── deobfuscateparam.txt │ │ ├── distanceoftimeinwords.txt │ │ ├── endformtag.txt │ │ ├── excerpt.txt │ │ ├── filefield.txt │ │ ├── filefieldtag.txt │ │ ├── filterchain.txt │ │ ├── filters.txt │ │ ├── flash.txt │ │ ├── flashclear.txt │ │ ├── flashcount.txt │ │ ├── flashdelete.txt │ │ ├── flashinsert.txt │ │ ├── flashisempty.txt │ │ ├── flashkeep.txt │ │ ├── flashkeyexists.txt │ │ ├── flashmessages.txt │ │ ├── get.txt │ │ ├── hasmanycheckbox.txt │ │ ├── hasmanyradiobutton.txt │ │ ├── hiddenfield.txt │ │ ├── hiddenfieldtag.txt │ │ ├── highlight.txt │ │ ├── hourselecttag.txt │ │ ├── humanize.txt │ │ ├── hyphenize.txt │ │ ├── imagetag.txt │ │ ├── includecontent.txt │ │ ├── includedinobject.txt │ │ ├── includelayout.txt │ │ ├── includepartial.txt │ │ ├── isajax.txt │ │ ├── isget.txt │ │ ├── ispost.txt │ │ ├── issecure.txt │ │ ├── javascriptincludetag.txt │ │ ├── linkto.txt │ │ ├── mailto.txt │ │ ├── mimetypes.txt │ │ ├── minuteselecttag.txt │ │ ├── model.txt │ │ ├── monthselecttag.txt │ │ ├── obfuscateparam.txt │ │ ├── onlyprovides.txt │ │ ├── pagination.txt │ │ ├── paginationlinks.txt │ │ ├── passwordfield.txt │ │ ├── passwordfieldtag.txt │ │ ├── pluginnames.txt │ │ ├── pluralize.txt │ │ ├── provides.txt │ │ ├── radiobutton.txt │ │ ├── radiobuttontag.txt │ │ ├── redirectto.txt │ │ ├── rendernothing.txt │ │ ├── renderpartial.txt │ │ ├── rendertext.txt │ │ ├── renderview.txt │ │ ├── renderwith.txt │ │ ├── resetcycle.txt │ │ ├── response.txt │ │ ├── secondselecttag.txt │ │ ├── select.txt │ │ ├── selecttag.txt │ │ ├── sendemail.txt │ │ ├── sendfile.txt │ │ ├── set.txt │ │ ├── setfilterchain.txt │ │ ├── setpagination.txt │ │ ├── setresponse.txt │ │ ├── setverificationchain.txt │ │ ├── simpleformat.txt │ │ ├── singularize.txt │ │ ├── startformtag.txt │ │ ├── striplinks.txt │ │ ├── striptags.txt │ │ ├── stylesheetlinktag.txt │ │ ├── submittag.txt │ │ ├── textarea.txt │ │ ├── textareatag.txt │ │ ├── textfield.txt │ │ ├── textfieldtag.txt │ │ ├── timeagoinwords.txt │ │ ├── timeselect.txt │ │ ├── timeselecttags.txt │ │ ├── timeuntilinwords.txt │ │ ├── titleize.txt │ │ ├── truncate.txt │ │ ├── urlfor.txt │ │ ├── useslayout.txt │ │ ├── verificationchain.txt │ │ ├── verifies.txt │ │ ├── wordtruncate.txt │ │ └── yearselecttag.txt │ │ ├── deprecated │ │ └── findorcreateby[property].txt │ │ ├── mapper │ │ ├── collection.txt │ │ ├── delete.txt │ │ ├── end.txt │ │ ├── get.txt │ │ ├── mapper.txt │ │ ├── member.txt │ │ ├── namespace.txt │ │ ├── package.txt │ │ ├── patch.txt │ │ ├── post.txt │ │ ├── put.txt │ │ ├── resource.txt │ │ ├── resources.txt │ │ ├── root.txt │ │ ├── scope.txt │ │ └── wildcard.txt │ │ ├── migration │ │ ├── addcolumn.txt │ │ ├── addindex.txt │ │ ├── addrecord.txt │ │ ├── changecolumn.txt │ │ ├── changetable.txt │ │ ├── createtable.txt │ │ ├── down.txt │ │ ├── removeindex.txt │ │ └── up.txt │ │ ├── migrator │ │ ├── createmigration.txt │ │ ├── getavailablemigrations.txt │ │ ├── getcurrentmigrationversion.txt │ │ └── migrateto.txt │ │ └── model │ │ ├── accessibleproperties.txt │ │ ├── adderror.txt │ │ ├── adderrortobase.txt │ │ ├── aftercreate.txt │ │ ├── afterdelete.txt │ │ ├── afterfind.txt │ │ ├── afterinitialization.txt │ │ ├── afternew.txt │ │ ├── aftersave.txt │ │ ├── afterupdate.txt │ │ ├── aftervalidation.txt │ │ ├── aftervalidationoncreate.txt │ │ ├── aftervalidationonupdate.txt │ │ ├── allchanges.txt │ │ ├── allerrors.txt │ │ ├── automaticvalidations.txt │ │ ├── average.txt │ │ ├── beforecreate.txt │ │ ├── beforedelete.txt │ │ ├── beforesave.txt │ │ ├── beforeupdate.txt │ │ ├── beforevalidation.txt │ │ ├── beforevalidationoncreate.txt │ │ ├── beforevalidationonupdate.txt │ │ ├── belongsto.txt │ │ ├── changedfrom.txt │ │ ├── changedproperties.txt │ │ ├── clearchangeinformation.txt │ │ ├── clearerrors.txt │ │ ├── count.txt │ │ ├── create.txt │ │ ├── datasource.txt │ │ ├── delete.txt │ │ ├── deleteall.txt │ │ ├── deletebykey.txt │ │ ├── deleteone.txt │ │ ├── errorcount.txt │ │ ├── errormessageon.txt │ │ ├── errormessagesfor.txt │ │ ├── errorson.txt │ │ ├── errorsonbase.txt │ │ ├── exists.txt │ │ ├── findall.txt │ │ ├── findallkeys.txt │ │ ├── findbykey.txt │ │ ├── findone.txt │ │ ├── gettablenameprefix.txt │ │ ├── haschanged.txt │ │ ├── haserrors.txt │ │ ├── hasmany.txt │ │ ├── hasone.txt │ │ ├── hasproperty.txt │ │ ├── invokewithtransaction.txt │ │ ├── isclass.txt │ │ ├── isinstance.txt │ │ ├── isnew.txt │ │ ├── key.txt │ │ ├── maximum.txt │ │ ├── minimum.txt │ │ ├── nestedproperties.txt │ │ ├── new.txt │ │ ├── primarykey.txt │ │ ├── primarykeys.txt │ │ ├── properties.txt │ │ ├── property.txt │ │ ├── propertyispresent.txt │ │ ├── propertynames.txt │ │ ├── protectedproperties.txt │ │ ├── reload.txt │ │ ├── save.txt │ │ ├── setprimarykey.txt │ │ ├── setprimarykeys.txt │ │ ├── setproperties.txt │ │ ├── settablenameprefix.txt │ │ ├── sum.txt │ │ ├── table.txt │ │ ├── tablename.txt │ │ ├── toggle.txt │ │ ├── update.txt │ │ ├── updateall.txt │ │ ├── updatebykey.txt │ │ ├── updateone.txt │ │ ├── updateproperty.txt │ │ ├── valid.txt │ │ ├── validate.txt │ │ ├── validateoncreate.txt │ │ ├── validateonupdate.txt │ │ ├── validatesconfirmationof.txt │ │ ├── validatesexclusionof.txt │ │ ├── validatesformatof.txt │ │ ├── validatesinclusionof.txt │ │ ├── validateslengthof.txt │ │ ├── validatesnumericalityof.txt │ │ ├── validatespresenceof.txt │ │ ├── validatesuniquenessof.txt │ │ └── validationtypeforproperty.txt ├── functions.cfm ├── helpers.cfm ├── includes.cfm ├── initialization.cfm ├── layout │ ├── _footer.cfm │ ├── _footer_simple.cfm │ ├── _header.cfm │ ├── _header_simple.cfm │ └── _navigation.cfm ├── migrator │ ├── _navigation.cfm │ ├── command.cfm │ ├── sql.cfm │ └── templating.cfm ├── routes.cfm ├── tests │ ├── _navigation.cfm │ ├── html.cfm │ ├── json.cfm │ ├── junit.cfm │ └── txt.cfm └── views │ ├── cli.cfm │ ├── congratulations.cfm │ ├── docs.cfm │ ├── info.cfm │ ├── migrator.cfm │ ├── packages.cfm │ ├── pluginentry.cfm │ ├── plugins.cfm │ ├── routes.cfm │ ├── routetester.cfm │ ├── templating.cfm │ └── tests.cfm ├── test └── functions.cfm ├── vendor └── toXml │ └── toXML.cfc └── view ├── assets.cfm ├── csrf.cfm ├── errors.cfm ├── forms.cfm ├── formsassociation.cfm ├── formsdate.cfm ├── formsdateobject.cfm ├── formsdateplain.cfm ├── formsobject.cfm ├── formsplain.cfm ├── functions.cfm ├── links.cfm ├── miscellaneous.cfm └── sanitize.cfm /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: cfwheels 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | CFIDE 3 | cfide 4 | WEB-INF 5 | /target 6 | /.settings 7 | /.classpath 8 | /temp/ 9 | /bluedragon/ 10 | /manual/ 11 | /subfolder/ 12 | /bin/ 13 | /migrator/sql/ 14 | cfwheels.*.zip 15 | settings.json 16 | .vscode 17 | /plugins/**/ 18 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | Options +FollowSymLinks 2 | RewriteEngine On 3 | RewriteCond %{REQUEST_URI} ^.*/index.cfm/(.*)$ [NC] 4 | RewriteRule ^.*/index.cfm/(.*)$ ./rewrite.cfm/$1 [NS,L] 5 | RewriteCond %{REQUEST_URI} !^.*/(flex2gateway|jrunscripts|cfide|cf_scripts|cfformgateway|cffileservlet|lucee|files|images|javascripts|miscellaneous|stylesheets|wheels/public/assets|robots.txt|favicon.ico|sitemap.xml|rewrite.cfm)($|/.*$) [NC] 6 | RewriteRule ^(.*)$ ./rewrite.cfm/$1 [NS,L] 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | sudo: required 3 | services: 4 | - mysql 5 | jdk: 6 | - oraclejdk8 7 | env: 8 | matrix: 9 | - CFENGINE=lucee@5 DB=MySQL DBCLASS=org.gjt.mm.mysql.Driver 10 | before_install: 11 | # Get Commandbox 12 | - sudo apt-key adv --keyserver keys.gnupg.net --recv 6DA70622 13 | - sudo echo "deb http://downloads.ortussolutions.com/debs/noarch /" | sudo tee -a /etc/apt/sources.list.d/commandbox.list 14 | install: 15 | # Install Commandbox 16 | - sudo apt-get update && sudo apt-get --assume-yes install commandbox 17 | # Install Wheels CLI 18 | - box version 19 | - box install cfwheels-cli 20 | # Install CFConfig 21 | - box install commandbox-cfconfig 22 | # Install CFWheels Example App from git master 23 | - box install cfwheels/cfwheels-example-app 24 | before_script: 25 | # Create database 26 | - if [[ "$DB" == "MySQL" ]]; then mysql -e 'CREATE DATABASE exampleapp;'; fi 27 | # Start The Server 28 | - box server start 29 | # Add the datasource via CFConfig 30 | - if [[ "$DB" == "MySQL" ]]; then box cfconfig datasource save name=exampleapp database=exampleapp dbdriver=$DB class="$DBCLASS" host=127.0.0.1 port=3306 username=travis password=""; fi 31 | # CFConfig seems to require a server restart to register the DB 32 | - box server restart 33 | # Basically, we now run the wheels CLI test runner, pointing it to the current server 34 | - box cfconfig datasource list 35 | # Double check servername? 36 | - box server list 37 | # Run DB Migrations 38 | script: > 39 | testResults="$(box wheels test type=app servername=exampleapp)"; 40 | echo "$testResults"; 41 | if ! grep -i "\Tests Complete: All Good!" <<< $testResults; then exit 1; fi 42 | notifications: 43 | email: false 44 | -------------------------------------------------------------------------------- /Application.cfc: -------------------------------------------------------------------------------- 1 | component output="false" { 2 | include "wheels/functions.cfm"; 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CFWheels Example App 2 | 3 | ![ScreenShot](https://camo.githubusercontent.com/d2cda997b600d25b3ac7d2bd397aa8bd8ba893be/68747470733a2f2f6366776865656c732e6f72672f626c6f672f77702d636f6e74656e742f75706c6f6164732f323031382f30362f3132372e302e302e315f36303035305f61646d696e5f75736572732d65313532383239383635383535372e706e67) 4 | 5 | This sample application is *not* a complete Content Management System, and is more of a starting point for your own 6 | applications; it aims to demonstrate some of the framework's features such as Database migrations, routing etc. 7 | 8 | ## Installation 9 | 10 | See [Installation](https://github.com/cfwheels/cfwheels-example-app/wiki/Installation) 11 | 12 | ## Documentation 13 | 14 | See the [Wiki](https://github.com/cfwheels/cfwheels-example-app/wiki/Installation) 15 | 16 | ## Requirements 17 | 18 | - CommandBox (to run locally) 19 | - Tested on Lucee 5.2.7 / ACF 2016 20 | - MySQL 5.x 21 | -------------------------------------------------------------------------------- /config/development/settings.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Use this file to configure specific settings for the "development" environment. 4 | // A variable set in this file will override the one in "config/settings.cfm". 5 | 6 | // Example: 7 | // set(dataSourceName="devDB"); 8 | 9 | 10 | -------------------------------------------------------------------------------- /config/environment.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Use this file to set the current environment for your application. 4 | // You can set it to "development", "testing", "maintenance" or "production". 5 | // Don't forget to issue a reload request (e.g. reload=true) after making changes. 6 | // See http://docs.cfwheels.org/docs/switching-environments for more info. 7 | 8 | // Below, we have set it to "development" for you since that is convenient when you are building your application. 9 | // We recommend that you change this to "production" when you're running your application live. 10 | set(environment="development"); 11 | 12 | 13 | -------------------------------------------------------------------------------- /config/maintenance/settings.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Use this file to configure specific settings for the "maintenance" environment. 4 | // A variable set in this file will override the one in "config/settings.cfm". 5 | 6 | // Example: 7 | // set(ipExceptions="an.ip.num.ber"); 8 | 9 | 10 | -------------------------------------------------------------------------------- /config/production/settings.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Use this file to configure specific settings for the "production" environment. 4 | // A variable set in this file will override the one in "config/settings.cfm". 5 | 6 | // Example: 7 | // set(errorEmailAddress="someone@somewhere.com"); 8 | 9 | // Automagically migrate the database if in production mode 10 | //set(autoMigrateDatabase=true); 11 | 12 | -------------------------------------------------------------------------------- /config/testing/settings.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Use this file to configure specific settings for the "testing" environment. 4 | // A variable set in this file will override the one in "config/settings.cfm". 5 | 6 | // Example: 7 | // set(cacheQueries=false); 8 | 9 | 10 | -------------------------------------------------------------------------------- /controllers/Main.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.controllers.Controller" { 2 | 3 | function config() { 4 | super.config(); 5 | } 6 | 7 | function index(){ 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /controllers/admin/Permissions.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.controllers.Controller" { 2 | 3 | function config() { 4 | super.config(restrictAccess=true); 5 | verifies(except="index", params="key", paramsTypes="integer", handler="objectNotFound"); 6 | filters(through="filterGetAllRoles"); 7 | } 8 | 9 | /** 10 | * View all permissions 11 | **/ 12 | function index() { 13 | allroles=model("role").findAll(order="name"); 14 | allpermissions=model("permission").findAll(); 15 | } 16 | 17 | /** 18 | * Edit permission 19 | **/ 20 | function edit() { 21 | permission=model("permission").findByKey(key=params.key, include="rolepermissions"); 22 | } 23 | 24 | /** 25 | * Update permission 26 | **/ 27 | function update() { 28 | permission=model("permission").findByKey(params.key); 29 | if(permission.update(params.permission)){ 30 | redirectTo(action="index", success="Permission successfully updated: you must reload the application for these to take effect."); 31 | } else { 32 | renderView(action="edit"); 33 | } 34 | } 35 | 36 | /** 37 | * Redirect away if verifies fails, or if an object can't be found 38 | **/ 39 | private function objectNotFound() { 40 | redirectTo(action="index", error="That permission wasn't found"); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /controllers/admin/Roles.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.controllers.Controller" { 2 | 3 | function config() { 4 | super.config(restrictAccess=true); 5 | verifies(except="index,new,create", params="key", paramsTypes="integer", handler="objectNotFound"); 6 | } 7 | 8 | /** 9 | * View all roles 10 | **/ 11 | function index() { 12 | roles=model("role").findAll(); 13 | } 14 | /** 15 | * Add New Role 16 | **/ 17 | function new() { 18 | role=model("Role").new(); 19 | } 20 | 21 | /** 22 | * Create Role 23 | **/ 24 | function create() { 25 | role=model("Role").create(params.Role); 26 | if(Role.hasErrors()){ 27 | renderView(action="new"); 28 | } else { 29 | redirectTo(action="index", success="Role successfully created"); 30 | } 31 | } 32 | /** 33 | * Edit role 34 | **/ 35 | function edit() { 36 | role=model("role").findByKey(params.key); 37 | } 38 | 39 | /** 40 | * Update role 41 | **/ 42 | function update() { 43 | role=model("role").findByKey(params.key); 44 | if(role.update(params.role)){ 45 | redirectTo(action="index", success="Role successfully updated"); 46 | } else { 47 | renderView(action="edit"); 48 | } 49 | } 50 | 51 | /** 52 | * Redirect away if verifies fails, or if an object can't be found 53 | **/ 54 | private function objectNotFound() { 55 | redirectTo(action="index", error="That Role wasn't found"); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /controllers/admin/Settings.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.controllers.Controller" { 2 | 3 | function config() { 4 | super.config(restrictAccess=true); 5 | verifies(except="index", params="key", paramsTypes="integer", handler="objectNotFound"); 6 | } 7 | 8 | /** 9 | * View all settings 10 | **/ 11 | function index() { 12 | settings=model("setting").findAll(order="name"); 13 | settingCategories=[]; 14 | for(setting in settings){ 15 | var s=listFirst(setting.name, "_"); 16 | if(!arrayFind(settingCategories, s)){ 17 | arrayAppend(settingCategories, s); 18 | } 19 | } 20 | } 21 | 22 | /** 23 | * Edit setting 24 | **/ 25 | function edit() { 26 | setting=model("setting").findByKey(key=params.key, where="editable = 1"); 27 | } 28 | 29 | /** 30 | * Update setting 31 | **/ 32 | function update() { 33 | setting=model("setting").findByKey(key=params.key, where="editable = 1"); 34 | if(setting.update(params.setting)){ 35 | redirectTo(action="index", success="Setting successfully updated: you must reload the application for these to take effect."); 36 | } else { 37 | renderView(action="edit"); 38 | } 39 | } 40 | 41 | /** 42 | * Redirect away if verifies fails, or if an object can't be found 43 | **/ 44 | private function objectNotFound() { 45 | redirectTo(action="index", error="That Setting wasn't found"); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /controllers/functions/auth.cfm: -------------------------------------------------------------------------------- 1 | 2 | //===================================================================== 3 | //= Controller Only Authentication Functions 4 | //===================================================================== 5 | /** 6 | * Used as a filter, and will redirect to login if not auth'd 7 | * If logged in and permission is still invalid, denies with 403. 8 | * Typically you would not call this filter directly, but use `super.config(restrictAccess=true)` in your subcontroller 9 | * 10 | * [section: Application] 11 | * [category: Authentication] 12 | **/ 13 | private function checkPermissionAndRedirect(){ 14 | if(!hasPermission()) 15 | if(isAuthenticated()){ 16 | throw(type="app.AccessDenied", message="You have insufficient permission to access this resource"); 17 | } else { 18 | redirectTo(route="login", error="Login Required"); 19 | //redirectTo(route="login", error="Login Required", params="?referrer=#cgi.PATH_INFO#"); 20 | } 21 | } 22 | 23 | /** 24 | * Redirect user away if logged in 25 | * 26 | * [section: Application] 27 | * [category: Authentication] 28 | */ 29 | private function redirectAuthenticatedUsers() { 30 | if(isAuthenticated()) 31 | redirectTo(route="root", info="Sorry, you can't access that functionality right now"); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /events/onabort.cfm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/events/onabort.cfm -------------------------------------------------------------------------------- /events/onapplicationend.cfm: -------------------------------------------------------------------------------- 1 | 2 | // Place code here that should be executed on the "onApplicationEnd" event. 3 | -------------------------------------------------------------------------------- /events/onapplicationstart.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Wrapping this in a try / catch and skipping the error, as otherwise you can't get to the migrations 4 | try { 5 | // Place code here that should be executed on the "onApplicationStart" event. // Application Settings 6 | application["settings"] = {}; 7 | 8 | // Change this! It's only used once for encrypting cookie contents, but 9 | // Still, use generateSecretKey("AES") to generate a new one. 10 | application.encryptionKey = "7NNEID99l07DySzq1LJnEA=="; 11 | createApplicationSettings(); 12 | } catch (any e) { 13 | WriteOutput("Error: " & e.message); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /events/onerror.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Denied!

6 |

7 | Sorry, but you're not allowed to access that. 8 |

9 |
10 | 11 | 12 |

Error!

13 |

14 | Sorry, that caused an unexpected error.
15 | Please try again later. 16 |

17 |
18 |
19 | 20 | -------------------------------------------------------------------------------- /events/onmaintenance.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Maintenance!

4 |

5 | Sorry, maintenance work is being performed.
6 | Please try again later. 7 |

-------------------------------------------------------------------------------- /events/onmissingtemplate.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 |

File Not Found!

4 |

5 | Sorry, the page you requested could not be found.
6 | Please verify the address. 7 |

-------------------------------------------------------------------------------- /events/onrequestend.cfm: -------------------------------------------------------------------------------- 1 | 2 | // Place code here that should be executed on the "onRequestEnd" event. 3 | -------------------------------------------------------------------------------- /events/onrequeststart.cfm: -------------------------------------------------------------------------------- 1 | 2 | // Place code here that should be executed on the "onRequestStart" event. 3 | /* 4 | If authenticated, try and force a refresh on any auth'd page to stop browser caching 5 | of potentially sensitive information 6 | */ 7 | if(isAuthenticated()){ 8 | cfheader(name="Cache-Control", value="no-store, must-revalidate"); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /events/onsessionend.cfm: -------------------------------------------------------------------------------- 1 | 2 | // Place code here that should be executed on the "onSessionEnd" event. 3 | -------------------------------------------------------------------------------- /events/onsessionstart.cfm: -------------------------------------------------------------------------------- 1 | 2 | // Place code here that should be executed on the "onSessionStart" event. 3 | -------------------------------------------------------------------------------- /files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/files/.keep -------------------------------------------------------------------------------- /global/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | //===================================================================== 3 | //= Global Functions 4 | //===================================================================== 5 | if (StructKeyExists(server, "lucee")) { 6 | include "install.cfm"; 7 | include "auth.cfm"; 8 | include "logging.cfm"; 9 | include "utils.cfm"; 10 | } else { 11 | // TODO: Check this doesn't break when in a subdir? 12 | include "/global/install.cfm"; 13 | include "/global/auth.cfm"; 14 | include "/global/logging.cfm"; 15 | include "/global/utils.cfm"; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /global/install.cfm: -------------------------------------------------------------------------------- 1 | 2 | //===================================================================== 3 | //= Installation 4 | //===================================================================== 5 | /** 6 | * Gets Called onApplicationStart, and loads database settings, default roles + permissions etc. 7 | * 8 | * [section: Application] 9 | * [category: Miscellaneous] 10 | * 11 | **/ 12 | public function createApplicationSettings(){ 13 | 14 | // Load Application Settings 15 | local.settings=model("setting").findAll(); 16 | for(var setting in local.settings){ 17 | application.settings[setting.name]=deserializeJSON(setting.value); 18 | } 19 | 20 | // Anon Level Permissions: these are the application level defaults 21 | local.permissions=model("permission").findAll(include="rolepermissions", where="roleid=4"); 22 | for(var permission in local.permissions){ 23 | application.permissions[permission.name]=true; 24 | } 25 | 26 | // Role Level Permissions also cached in application scope for easier lookup 27 | local.allpermissions=model("permission").findAll( order="name", include="rolepermissions(role)"); 28 | local.allroles= model("role").findAll(select="name", order="name"); 29 | local.rolepermissions={}; 30 | 31 | for( var role in local.allroles){ 32 | local.rolepermissions[role.name]={}; 33 | cfloop(query=local.allpermissions, group="id"){ 34 | if(rolename != ""){ 35 | cfloop(){ 36 | local.rolepermissions[rolename][name]=true; 37 | } 38 | } 39 | } 40 | } 41 | 42 | application.rolepermissions=local.rolepermissions; 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /global/logging.cfm: -------------------------------------------------------------------------------- 1 | 2 | //===================================================================== 3 | //= Logging 4 | //===================================================================== 5 | 6 | /** 7 | * Adds a logline to the Audit Log: doesn't log anything in testing mode 8 | * 9 | * [section: Application] 10 | * [category: Utils] 11 | * 12 | * @type Anything you want to group by: i.e, email | database | user | auth | login | flash etc. 13 | * @message The Message 14 | * @severity One of info | warning | danger 15 | * @data Arbitary data to store alongside this log line. will be serialized 16 | * @createdBy Username of who fired the log line 17 | */ 18 | public void function addLogLine(required string type, required string message, string severity="info", any data, string createdBy="Anon"){ 19 | if(!structKeyExists(request, "isTestingMode")){ 20 | if(isAuthenticated()){ 21 | arguments.createdBy=getSession().user.properties.firstname & ' ' & getSession().user.properties.lastname; 22 | } 23 | arguments.ipaddress=getIPAddress(); 24 | local.newLogLine=model("auditlog").create(arguments); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/images/.keep -------------------------------------------------------------------------------- /index.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "wheels/index.cfm"; 3 | 4 | -------------------------------------------------------------------------------- /javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/javascripts/.keep -------------------------------------------------------------------------------- /javascripts/custom.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function($) { 2 | 3 | // Logging modals 4 | $('#logModalCenter').on('show.bs.modal', function (e) { 5 | var link = $(e.relatedTarget); 6 | var modal = $(this); 7 | $.get( link.data('remoteurl'), function(r){ 8 | var highlighted = syntaxHighlight( JSON.stringify(r, undefined, 4) ); 9 | modal.find('.modal-body').html( 10 | "
" + highlighted + "
" 11 | ); 12 | }); 13 | }); 14 | 15 | // Logging highlighting 16 | function syntaxHighlight(json) { 17 | json = json.replace(/&/g, '&').replace(//g, '>'); 18 | return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { 19 | var cls = 'number'; 20 | if (/^"/.test(match)) { 21 | if (/:$/.test(match)) { 22 | cls = 'key'; 23 | } else { 24 | cls = 'string'; 25 | } 26 | } else if (/true|false/.test(match)) { 27 | cls = 'boolean'; 28 | } else if (/null/.test(match)) { 29 | cls = 'null'; 30 | } 31 | return '' + match + ''; 32 | }); 33 | } 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /miscellaneous/Application.cfc: -------------------------------------------------------------------------------- 1 | /* 2 | You can place CFML code in this folder and run it independently from CFWheels. 3 | This empty "Application.cfc" file makes sure that CFWheels does not interfere with the request. 4 | */ 5 | component { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /models/Auditlog.cfc: -------------------------------------------------------------------------------- 1 | component extends="Model" 2 | { 3 | function config() { 4 | // Properties 5 | validatesPresenceOf("message,type,severity,createdBy,ipaddress"); 6 | afterNew("serializeExtendedData"); 7 | } 8 | 9 | /** 10 | * If anything is passed into data, serialize if at all possible 11 | */ 12 | function serializeExtendedData() { 13 | if(structKeyExists(this, "data")) 14 | this.data=serializeJSON(this.data); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /models/Permission.cfc: -------------------------------------------------------------------------------- 1 | component extends="Model" 2 | { 3 | function config() { 4 | // Associations 5 | hasMany(name="rolepermissions", jointype="left"); 6 | hasMany(name="userpermissions"); 7 | nestedProperties(associations="rolepermissions,userpermissions", allowDelete=true); 8 | 9 | // Properties 10 | validatesUniquenessOf("name"); 11 | validatesPresenceOf("name,type"); 12 | validatesInclusionOf( 13 | property="type", 14 | list="named,controller", message="Invalid Permission Type" ); 15 | 16 | beforeValidation("validatePermissionName"); 17 | 18 | } 19 | 20 | /** 21 | * This is a bit lazy. Really should use regEx. 22 | **/ 23 | function validatePermissionName(){ 24 | if(structKeyExists(this, "name") && structKeyExists(this, "type")){ 25 | if(this.type == 'named'){ 26 | if(this.name CONTAINS "." || this.name CONTAINS " "){ 27 | addError(property="name", message="Named Permission Name should not contain dots or spaces"); 28 | } 29 | } 30 | if(this.type == 'controller'){ 31 | if(this.name CONTAINS " "){ 32 | addError(property="name", message="Controller Permission Name should not contain spaces"); 33 | } 34 | } 35 | } 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /models/Role.cfc: -------------------------------------------------------------------------------- 1 | component extends="Model" { 2 | 3 | function config() { 4 | // Associations 5 | hasMany("rolepermissions"); 6 | 7 | // Properties 8 | validatesPresenceOf("name"); 9 | validatesUniquenessOf(properties="name", message="Role name must be unique"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /models/RolePermission.cfc: -------------------------------------------------------------------------------- 1 | component extends="Model" { 2 | 3 | function config() { 4 | // Associations 5 | belongsTo("role"); 6 | belongsTo("permission"); 7 | 8 | // Properties 9 | validatesPresenceOf("roleid,permissionid"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /models/Setting.cfc: -------------------------------------------------------------------------------- 1 | component extends="Model" { 2 | 3 | function config() { 4 | // Properties 5 | validatesPresenceOf("name,description,type,value,editable"); 6 | validatesUniquenessOf(properties="name", message="Setting name must be unique"); 7 | validatesFormatOf(property="editable", type="boolean"); 8 | validatesInclusionOf(property="type", list="select,boolean,textfield", message="Invalid Setting Type" ); 9 | 10 | beforeValidation("serializeValue"); 11 | afterFind("deserializeValue"); 12 | } 13 | 14 | // If updating a setting, serialize its value 15 | function serializeValue(){ 16 | if(structKeyExists(this, "value") && !isJSON(this.value)) 17 | this.value=serializeJSON(this.value); 18 | } 19 | 20 | // Deserialize Setting Value after find - used in when updating application settings 21 | function deserializeValue(){ 22 | if(structKeyExists(this, "value") && isJSON(this.value)) 23 | this.value=deserializeJSON(this.value); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /models/UserPermission.cfc: -------------------------------------------------------------------------------- 1 | component extends="Model" { 2 | 3 | function config() { 4 | // Associations 5 | belongsTo("user"); 6 | belongsTo("permission"); 7 | 8 | // Properties 9 | validatesPresenceOf("userid,permissionid"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /plugins/.keep: -------------------------------------------------------------------------------- 1 | /*.zip 2 | /*/ 3 | -------------------------------------------------------------------------------- /plugins/FlashMessagesBootstrap-1.0.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/plugins/FlashMessagesBootstrap-1.0.2.zip -------------------------------------------------------------------------------- /plugins/authenticateThis-1.0.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/plugins/authenticateThis-1.0.1.zip -------------------------------------------------------------------------------- /plugins/jsconfirm-1.0.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/plugins/jsconfirm-1.0.5.zip -------------------------------------------------------------------------------- /rewrite.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "wheels/index.cfm"; 3 | 4 | -------------------------------------------------------------------------------- /root.cfm: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /server-exampleappACF.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"exampleappACF", 3 | "web":{ 4 | "http":{ 5 | "host":"localhost", 6 | "port":60051 7 | }, 8 | "rewrites":{ 9 | "enable":true, 10 | "config":"urlrewrite.xml" 11 | } 12 | }, 13 | "app":{ 14 | "cfengine":"adobe@2016" 15 | } 16 | } -------------------------------------------------------------------------------- /server.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"exampleapp", 3 | "web":{ 4 | "http":{ 5 | "host":"localhost", 6 | "port":60050 7 | }, 8 | "rewrites":{ 9 | "enable":true, 10 | "config":"urlrewrite.xml" 11 | } 12 | }, 13 | "app":{ 14 | "cfengine":"lucee@5" 15 | } 16 | } -------------------------------------------------------------------------------- /stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wheels-dev/cfwheels-example-app/6e6401b9e184798321748de08c8ffbce51b16bdd/stylesheets/.keep -------------------------------------------------------------------------------- /stylesheets/custom.css: -------------------------------------------------------------------------------- 1 | /* form Fields */ 2 | .btn-pushdown { 3 | margin-top: 25px; 4 | } 5 | /* Errors */ 6 | ul.alert.alert-danger { 7 | padding: 15px; 8 | margin-bottom: 20px; 9 | border: 1px solid; 10 | border-radius: 4px; 11 | color: #a94442; 12 | background-color: #f2dede; 13 | border-color: #ebccd1; 14 | } 15 | ul.alert.alert-danger li { 16 | margin-left:26px; 17 | } 18 | .field-with-errors .control-label {color: #a94442;} 19 | .field-with-errors .form-control {border-color: #a94442;} 20 | 21 | dl { 22 | width: 100%; 23 | overflow: hidden; 24 | padding: 0; 25 | margin: 0 26 | } 27 | dt { 28 | float: left; 29 | width: 50%; 30 | padding: 0; 31 | margin: 0 32 | } 33 | dd { 34 | float: left; 35 | width: 50%; 36 | /* adjust the width; make sure the total of both is 100% */ 37 | background: #dd0 38 | padding: 0; 39 | margin: 0 40 | } 41 | 42 | /* Log Code Formatting */ 43 | .modal-body .string { color: green; } 44 | .modal-body .number { color: darkorange; } 45 | .modal-body .boolean { color: blue; } 46 | .modal-body .null { color: magenta; } 47 | .modal-body .key { color: red; } 48 | 49 | /* Report Range Picker */ 50 | #reportrange { 51 | cursor: pointer; 52 | padding: 5px 10px; 53 | } 54 | -------------------------------------------------------------------------------- /tests/functions/Utils.cfc: -------------------------------------------------------------------------------- 1 | component extends="tests.Test" { 2 | 3 | function setup() { 4 | super.setup(); 5 | } 6 | function teardown() { 7 | super.teardown(); 8 | } 9 | 10 | function Test_convertStringToStruct(){ 11 | str="foo.bar"; 12 | r=convertStringToStruct(str, "howdy"); 13 | assert("isStruct(r) EQ true"); 14 | assert("r.foo.bar EQ 'howdy'"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/functions/models/Auditlog.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.tests.Test" { 2 | 3 | function setup(){ 4 | super.setup(); 5 | params = { 6 | "message" = "This is a test Log Message", 7 | "type" = "testsuite", 8 | "severity" = "info", 9 | "createdBy" = "TestSuite", 10 | "ipaddress" = "0.0.0.0" 11 | }; 12 | } 13 | 14 | function teardown(){ 15 | super.teardown(); 16 | } 17 | 18 | function test_validation_passes(){ 19 | log = model("auditlog").new(params); 20 | assert("log.valid()"); 21 | } 22 | 23 | function test_validation_fails(){ 24 | log = model("auditlog").new(); 25 | assert("!log.valid()"); 26 | } 27 | 28 | function test_data_simpleValue(){ 29 | params.data = "I am a string"; 30 | log = model("auditlog").new(params); 31 | r = log.properties(); 32 | assert("log.valid()"); 33 | assert("isJSON(r.data)"); 34 | } 35 | 36 | function test_data_array(){ 37 | params.data = ["one", "two", "three"]; 38 | log = model("auditlog").new(params); 39 | r = log.properties(); 40 | assert("log.valid()"); 41 | assert("isJSON(r.data)"); 42 | } 43 | 44 | function test_data_struct(){ 45 | params.data = { 46 | "one" = "foo", "two" = "bar", "three" = "baz" 47 | }; 48 | log = model("auditlog").new(params); 49 | r = log.properties(); 50 | assert("log.valid()"); 51 | assert("isJSON(r.data)"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/functions/models/Permission.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.tests.Test" { 2 | 3 | function setup(){ 4 | super.setup(); 5 | } 6 | 7 | function teardown(){ 8 | super.teardown(); 9 | } 10 | 11 | function test_isNotUnique(){ 12 | p = model("permission").new(); 13 | p.setProperties( 14 | name = "admin", type="controller" 15 | ); 16 | r = p.valid(); 17 | err = p.allErrors(); 18 | assert("r EQ false"); 19 | assert("err[1]['property'] EQ 'name'"); 20 | } 21 | 22 | function test_checkForType(){ 23 | p = model("permission").new(); 24 | p.setProperties( 25 | name = "foo.bar.baz", type="BADVALUE" 26 | ); 27 | r = p.valid(); 28 | err = p.allErrors(); 29 | assert("r EQ false"); 30 | assert("err[1]['property'] EQ 'type'"); 31 | } 32 | 33 | function test_checkNameFormat_Spaces(){ 34 | p = model("permission").new(); 35 | p.setProperties( 36 | name = "I Should Fail", type="controller" 37 | ); 38 | r = p.valid(); 39 | err = p.allErrors(); 40 | assert("r EQ false"); 41 | assert("err[1]['property'] EQ 'name'"); 42 | } 43 | 44 | function test_checkNameFormat_Dots(){ 45 | p = model("permission").new(); 46 | p.setProperties( 47 | name = "admin.foo.abr", type="named" 48 | ); 49 | r = p.valid(); 50 | err = p.allErrors(); 51 | assert("r EQ false"); 52 | assert("err[1]['property'] EQ 'name'"); 53 | } 54 | 55 | function test_validation_passes(){ 56 | p = model("permission").new(); 57 | p.setProperties( 58 | name = "foo.bar.baz", type="controller" 59 | ); 60 | assert("p.valid()"); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/functions/models/Role.cfc: -------------------------------------------------------------------------------- 1 | component extends="app.tests.Test" { 2 | 3 | function setup(){ 4 | super.setup(); 5 | m=model("user").new(); 6 | } 7 | 8 | function teardown(){ 9 | super.teardown(); 10 | m={}; 11 | } 12 | 13 | function test_role_must_be_unique(){ 14 | m.name="admin"; 15 | assert("!m.valid()"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/requests/Accounts.cfc: -------------------------------------------------------------------------------- 1 | component extends="tests.Test" { 2 | 3 | 4 | function setup() { 5 | super.setup(); 6 | } 7 | function teardown() { 8 | super.teardown(); 9 | } 10 | 11 | function test_AccessAccount_with_Auth(){ 12 | loginFakeUser(); 13 | params= { 14 | controller="accounts", action="show" 15 | }; 16 | r=processRequest(params=params, returnAs="struct"); 17 | assert("r.body CONTAINS 'Your Account'"); 18 | assert("r.status EQ 200"); 19 | assert("r.redirect EQ ''"); 20 | } 21 | 22 | function test_AccessAccount_withOut_Auth(){ 23 | logoutFakeUser(); 24 | params= { 25 | controller="accounts", action="show" 26 | }; 27 | r=processRequest(params=params, returnAs="struct"); 28 | shouldLoginRedirect(); 29 | } 30 | 31 | function shouldLoginRedirect(){ 32 | assert("r.status EQ 302"); 33 | assert("r.redirect EQ '/login'"); 34 | assert("r.flash.error EQ 'Login Required'"); 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/requests/Main.cfc: -------------------------------------------------------------------------------- 1 | component extends="tests.Test" { 2 | 3 | 4 | function setup() { 5 | super.setup(); 6 | } 7 | function teardown() { 8 | super.teardown(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /tests/requests/Sessions.cfc: -------------------------------------------------------------------------------- 1 | component extends="tests.Test" { 2 | 3 | 4 | function setup() { 5 | super.setup(); 6 | } 7 | function teardown() { 8 | super.teardown(); 9 | } 10 | 11 | function test_session_new(){ 12 | params= { 13 | controller="sessions", action="new" 14 | }; 15 | r=processRequest(params=params, returnAs="struct"); 16 | assert("r.status EQ 200"); 17 | assert("!len(r.redirect)"); 18 | assert("r.body CONTAINS '
'"); 19 | } 20 | 21 | /* 22 | * Removing this for now as it still requires a valid user in the db to pass 23 | * Might re-add if we add a dedicated DB for testing 24 | function test_session_create_redirects_after_login(){ 25 | params= { 26 | controller="sessions", action="create", 27 | auth = { 28 | "email" = "admin@domain.com", 29 | "password" = "Password123!" 30 | } 31 | }; 32 | r=processRequest(params=params, returnAs="struct", method="POST"); 33 | debug("r"); 34 | assert("r.redirect EQ '/'"); 35 | assert("r.status EQ 302"); 36 | }*/ 37 | 38 | function test_session_create_invalid_rerenders_login_form(){ 39 | params= { 40 | controller="sessions", action="create", 41 | auth = { 42 | "email" = "badstuff", 43 | "password" = "wrongstuff" 44 | } 45 | }; 46 | r=processRequest(params=params, returnAs="struct", method="POST"); 47 | assert("r.body CONTAINS 'Email is invalid'"); 48 | assert("r.body CONTAINS 'Password must be at least 8 characters long and contain a mixture of numbers and letters'"); 49 | assert("r.status EQ 200"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /urlrewrite.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 28 | 29 | 30 | CFWheels pretty URLs 31 | ^/(flex2gateway|jrunscripts|cfide|cf_scripts|cfformgateway|cffileservlet|lucee|files|images|javascripts|miscellaneous|stylesheets|wheels/public/assets|robots.txt|favicon.ico|sitemap.xml|rewrite.cfm) 32 | ^/(.*)$ 33 | /rewrite.cfm/$1 34 | 35 | 36 | -------------------------------------------------------------------------------- /views/accounts/edit.cfm: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | #pageHeader(title="Edit Account", btn=linkTo(route="account", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 7 | 8 | #panel(title="Your Account Details", class="mb-4")# 9 | 10 | #errorMessagesFor("user")# 11 | #startFormTag(id="accountUpdateForm", route="account", method="patch")# 12 | 13 |
14 |
15 | #textField(objectName="user", property="firstname", label="First Name")# 16 |
17 |
18 | #textField(objectName="user", property="lastname", label="Last Name")# 19 |
20 |
21 |
22 |
23 | #textField(objectName="user", property="email", label="Email Address")# 24 | Your email address: used both as your login and also the source of your #linkTo(href="https://en.gravatar.com/", target="_blank", text="profile picture", title="Go to Gravatar")#. 25 |
26 |
27 | 28 | #submitTag(value="Update Your Details", class="mt-4 btn btn-success")# 29 | #endFormTag()# 30 | 31 | 32 | 33 | #panelEnd()# 34 |
35 | -------------------------------------------------------------------------------- /views/accounts/resetPassword.cfm: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | #pageHeader(title="Password Update Required")# 9 | 10 | #pageHeader(title="Update Password", btn=linkTo(route="account", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 11 | 12 | 13 | #panel(title="Update Your Password", class="mb-4")# 14 | 15 | #errorMessagesFor("user")# 16 | #startFormTag(id="accountUpdateForm", route="accountPassword", method="put")# 17 | 18 |
19 |
20 | #passwordField(objectName="user", property="oldpassword", label="Old Password")# 21 | Please enter your old password 22 |
23 |
24 |
25 |
26 | #passwordField(objectName="user", property="password", label="New Password")#Your new password 27 |
28 | 29 |
30 | #passwordField(objectName="user", property="passwordConfirmation", label="Confirm New Password")#Retype your new password 31 |
32 |
33 | 34 | #submitTag(value="Update Your Password", class="mt-4 btn btn-success")# 35 | #endFormTag()# 36 | 37 | 38 | #panelEnd()# 39 |
40 | -------------------------------------------------------------------------------- /views/accounts/show.cfm: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | #pageHeader(title="My Account", btn=linkTo(route='logout', class='btn btn-outline-danger', text='logout'))# 7 | 8 | #panel(title="Your Account Details", class="mb-4", 9 | btn="
" 10 | & linkTo(route="accountPassword", text="Change Password", class="btn btn-warning btn-sm") 11 | & linkTo(route="editAccount", text="Edit Details", class="btn btn-info btn-sm") 12 | & "
")# 13 | 14 |
15 |
16 |
#gravatar(email=user.email, size=160)#
17 |
18 |
19 | 20 |
First Name
21 |

#e(user.firstname)#

22 | 23 |
Last Name
24 |

#e(user.lastname)#

25 | 26 |
Email
27 |

#e(user.email)#

28 | 29 |
Last Logged In
30 |

#formatdate(user.loggedInAt)#

31 | 32 |
Password Last Updated
33 |

#timeAgoInWords(user.passwordResetAt)# agoNever

34 | 35 |
36 |
37 | 38 | #panelEnd()# 39 |
40 | -------------------------------------------------------------------------------- /views/admin/auditlogs/_modal.cfm: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /views/admin/auditlogs/index.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | #pageHeader(title="Logs")# 4 | #includePartial("filter")# 5 | #panel(title="Audit Log", class="mb-4")# 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
TypeMessageIPByDate
#logFileBadge(type=type, severity=severity)# 24 | 25 | #e(Message)# 26 | 27 | #e(Message)# 28 | 29 | 30 | #e(IPaddress)##truncate(e(createdBy), 14)##formatDate(createdAt)#
38 | #paginationLinks(route="logs")# 39 | 40 |
41 | Sorry
there are no Logs to display 42 |
43 |
44 | #panelEnd()# 45 | 46 | #includePartial("modal")# 47 |
48 | -------------------------------------------------------------------------------- /views/admin/permissions/_form.cfm: -------------------------------------------------------------------------------- 1 | 2 | #panel(title="Update Value for #e(permission.name)#", class="mb-4")# 3 |
4 |
5 |

#e(permission.description)#

6 |
7 |
8 | 9 | #hasManyCheckBox(objectName="permission", association="rolepermissions", keys="#id#,#permission.key()#", label=name)# 10 | 11 |
12 |
13 | #panelEnd()# 14 |
15 | -------------------------------------------------------------------------------- /views/admin/permissions/edit.cfm: -------------------------------------------------------------------------------- 1 | 2 | #pageHeader(title="Edit Permission", btn=linkTo(route="permissions", text=" Cancel and return", class="btn btn-info btn-xs", encode="attributes"))# 3 | 4 | #startFormTag(route="permission", key=permission.key(), method="put")# 5 | #includePartial("form")# 6 | #submitTag()# 7 | #endFormTag()# 8 | 9 | -------------------------------------------------------------------------------- /views/admin/roles/_form.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #panel(title="Role Details", class="mb-2")# 5 |
6 |
7 | #textField(objectName="role", property="name", label="Name")# 8 |
9 |
10 | #textField(objectName="role", property="description", label="Description")# 11 |
12 |
13 | #panelEnd()# 14 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /views/admin/roles/edit.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #pageHeader(title="Edit Role", btn=linkTo(route="roles", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 5 | 6 | 7 | #errorMessagesFor("role")# 8 | #startFormTag(id="roleEditForm", route="role", method="patch", key=params.key)# 9 | #includePartial("form")# 10 | #submitTag(value="Update Role", class="mt-4 btn btn-success")# 11 | #endFormTag()# 12 | 13 | -------------------------------------------------------------------------------- /views/admin/roles/index.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | #pageHeader(title="Roles", btn=linkTo(route="newRole", text=" New", class="btn btn-primary btn-xs", encode="attributes"))# 4 | #panel(title="Available Application Roles", class="mb-4")# 5 |
6 | Note: any changes here require a restart of the application to take effect 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 27 | 28 | 31 | 32 | 33 | 34 |
NameDescription
22 | #e(name)# 23 | 25 | #e(description)# 26 | 29 | #linkTo(route="editrole", key=id, text=" Edit", class="btn btn-sm btn-primary", encode=false)# 30 |
35 | 36 |
37 | Sorry
there are no Roles to display 38 |
39 |
40 | #panelEnd()# 41 |
42 | -------------------------------------------------------------------------------- /views/admin/roles/new.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #pageHeader(title="Create New Role", btn=linkTo(route="roles", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 5 | #errorMessagesFor("role")# 6 | #startFormTag(id="roleNewForm", route="roles")# 7 | #includePartial("form")# 8 | #submitTag(value="Create role", class="mt-4 btn btn-success")# 9 | #endFormTag()# 10 | 11 | -------------------------------------------------------------------------------- /views/admin/settings/_form.cfm: -------------------------------------------------------------------------------- 1 | 2 | #panel(title="Update Value for #e(setting.name)#", class="mb-4")# 3 |
4 |
5 | #e(setting.description)# 6 |
7 |
8 | 9 | 10 | #checkbox(objectname="setting", property="value", label="")# 11 | 12 | 13 | 14 | 15 | 16 | 17 | #select(objectname="setting", property="value", options=evaluate(replace(replace(setting.options, '[[', '', 'all'), ']]', '', 'all')))# 18 | 19 | #select(objectname="setting", property="value", options=setting.options)# 20 | 21 | 22 | 23 | 24 | #textField(objectname="setting", property="value")# 25 | 26 | 27 |
28 |
29 | 30 | #panelEnd()# 31 |
32 | -------------------------------------------------------------------------------- /views/admin/settings/edit.cfm: -------------------------------------------------------------------------------- 1 | 2 | #pageHeader(title="Edit Setting", btn=linkTo(route="settings", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 3 | 4 | #startFormTag(route="setting", key=setting.key(), method="put")# 5 | #includePartial("form")# 6 | #submitTag()# 7 | #endFormTag()# 8 | 9 | -------------------------------------------------------------------------------- /views/admin/users/_filter.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | #startFormTag(route="users", method="get", class="form-inline mb-2")# 8 |
9 |
10 | #selectTag(name="roleid", options=roles, includeBlank="All Roles", selected=params.roleid, label="Role", prependToLabel="
", labelClass="sr-only")# 11 |
12 |
13 | #selectTag(name="status", options="Active,Pending,Disabled,All", selected=params.status, label="Status", prependToLabel="
", labelClass="sr-only")# 14 |
15 | 16 |
17 | #textFieldTag(name="q", value=params.q, label="Keyword Search", labelClass="sr-only", placeholder="Keyword")# 18 |
19 | 20 |
21 | #submitTag(value="Filter", class="btn btn-info")# 22 |
23 |
24 | #endFormTag()# 25 | 26 | -------------------------------------------------------------------------------- /views/admin/users/edit.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #pageHeader(title="Edit User", btn=linkTo(route="users", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 5 | 6 | 7 | #errorMessagesFor("user")# 8 | #startFormTag(id="userEditForm", route="User", method="patch", key=params.key)# 9 | #includePartial("form/details")# 10 | #includePartial("form/role")# 11 | #submitTag(value="Update User", class="mt-4 btn btn-success")# 12 | #endFormTag()# 13 | 14 | -------------------------------------------------------------------------------- /views/admin/users/form/_auth.cfm: -------------------------------------------------------------------------------- 1 | 2 | #panel(title="Initial Password", class="mb-2")# 3 |
4 |
5 | #passwordField(objectName="user", property="password", label="Password")# 6 |
7 | 8 |
9 | #passwordField(objectName="user", property="passwordConfirmation", label="Confirm Password")# 10 |
11 |
12 | #panelEnd()# 13 |
14 | -------------------------------------------------------------------------------- /views/admin/users/form/_details.cfm: -------------------------------------------------------------------------------- 1 | 2 | #panel(title="User Details", class="mb-2")# 3 |
4 |
5 | #textField(objectName="user", property="firstname", label="First Name")# 6 |
7 |
8 | #textField(objectName="user", property="lastname", label="Last Name")# 9 |
10 |
11 |
12 |
13 | #textField(objectName="user", property="email", label="Email Address")# 14 |
15 |
16 | 17 |
18 |
19 | #textArea(objectName="user", property="adminNotes", label="Administrative Notes")# 20 | These can only be seen by those with the appropriate permission 21 |
22 |
23 |
24 | #panelEnd()# 25 |
26 | -------------------------------------------------------------------------------- /views/admin/users/form/_role.cfm: -------------------------------------------------------------------------------- 1 | 2 | #panel(title="User Options", class="mb-2")# 3 |
4 |
5 | #select(objectName="user", property="roleid", options=roles, label="Role")# 6 |
7 |
8 | #checkBox(objectname="user", property="verified", label="Verified")# 9 | #checkbox(objectName="user", property="passwordchangerequired", label="Require Change of Password on Next Login")# 10 |
11 |
12 | #panelEnd()# 13 |
14 | 15 | -------------------------------------------------------------------------------- /views/admin/users/new.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #pageHeader(title="Create New User", btn=linkTo(route="users", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 5 | #errorMessagesFor("user")# 6 | #startFormTag(id="userNewForm", route="Users")# 7 | #includePartial("form/details")# 8 | #includePartial("form/role")# 9 | #includePartial("form/auth")# 10 | #submitTag(value="Create User", class="mt-4 btn btn-success")# 11 | #endFormTag()# 12 | 13 | -------------------------------------------------------------------------------- /views/emails/passwordReset.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | #includePartial("/emails/header")# 4 | 5 |

Password Reset

6 | 7 |

Hi #user.firstname#, 8 |

We've received a request to reset your password. Click the link below to reset your password: 9 |

#linkto(route="editPasswordreset", onlyPath=false, token=user.passwordResetToken)# 10 |


If you did not request a password reset, please ignore this message. Your password will remain the same.

11 | 12 | #includePartial("/emails/footer")# 13 | 14 |
15 | -------------------------------------------------------------------------------- /views/emails/passwordResetAdmin.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #includePartial("/emails/header")# 5 | 6 |

Your New Temporary Password

7 | 8 |

Hi #user.firstname#, 9 |

An administrator has reset your password to: 10 |

#tempPassword# 11 |


You will be required to change this password on your next login.

12 | 13 | #includePartial("/emails/footer")# 14 | 15 |
16 | -------------------------------------------------------------------------------- /views/emails/passwordResetAdminPlain.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Your New Temporary Password 5 | 6 | Hi #user.firstname#, 7 | 8 | An administrator has reset your password to: 9 | 10 | #tempPassword# 11 | 12 | You will be required to change this password on your next login. 13 | 14 | 15 | -------------------------------------------------------------------------------- /views/emails/passwordResetPlain.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Password Reset 4 | 5 | Hi #user.firstname#, 6 | 7 | We've received a request to reset your password. Visit the link below to reset your password: 8 | 9 | #urlFor(route="editPasswordreset", onlyPath=false, token=user.passwordResetToken)# 10 | 11 | If you did not request a password reset, please ignore this message. Your password will remain the same. 12 | 13 | -------------------------------------------------------------------------------- /views/emails/verify.cfm: -------------------------------------------------------------------------------- 1 | 2 | #includePartial("/emails/header")# 3 | 4 |

Account Verification

5 | 6 |

Hi #user.firstname#, 7 |

Thank you for taking the time to create an account. 8 |

In order to complete your registration, we need to verify your email address. Please use the link below to verify your account: 9 |

#linkto(route="verify", onlyPath=false, token=user.verificationToken)#

10 | 11 | #includePartial("/emails/footer")# 12 |
13 | -------------------------------------------------------------------------------- /views/emails/verifyPlain.cfm: -------------------------------------------------------------------------------- 1 | 2 | Account Verification 3 | 4 | Hi #user.firstname#, 5 | Thank you for taking the time to create an account. 6 | In order to complete your registration, we need to verify your email address. Please use the link below to verify your account: 7 | #linkto(route="verify", onlyPath=false, token=user.verificationToken)# 8 | 9 | -------------------------------------------------------------------------------- /views/layout/_footer.cfm: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 |
7 |

#getSetting('general_copyright')# © #year(now())#

8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /views/main/index.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | #pageHeader(title="Welcome")# 4 | 5 |

This is an example App using CFWheels 2.x and some Bootstrap

6 | 7 |

Why don't you #linkTo(route="login", text="Login?")#

8 | 9 |

Cool beans bro. Check out your #linkTo(route="account", text="Account")#.

10 |
11 |
12 | -------------------------------------------------------------------------------- /views/passwordresets/edit.cfm: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 |
7 |
8 | #errorMessagesFor("user")# 9 | #panel(title="Reset Password")# 10 | #startFormTag(route="updatePasswordreset", method="put", token=params.token)# 11 | #passwordField(objectname="user", property="password", label="Password *", required="true")# 12 | #passwordField(objectname="user", property="passwordConfirmation", label="Confirm Password *", required="true")# 13 | #submitTag(value="Update Password", class="btn btn-block btn-primary")# 14 | #endFormTag()# 15 | #panelEnd()# 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /views/passwordresets/new.cfm: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 |
7 | #panel(title="Reset Password")# 8 | #startFormTag(route="Passwordreset")# 9 | #textFieldTag(name="email", label="Email")# 10 | #submitTag(value="Send Password Reset Email", class="btn btn-block btn-primary")# 11 | #endFormTag()# 12 |

#linkTo(route="root", text="Cancel")#

13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /views/register/new.cfm: -------------------------------------------------------------------------------- 1 | 4 | 5 | #pageHeader(title="Create Account", btn=linkTo(route="login", text=" Cancel", class="btn btn-info btn-xs", encode="attributes"))# 6 | 7 | 8 | #errorMessagesFor("user")# 9 | 10 | #startFormTag(id="registrationForm", route="register")# 11 | 12 |
13 |
14 | 15 | #panel(title="Your Details", class="mb-4")# 16 |
17 |
18 | #textField(objectName="user", property="firstname", label="First Name")# 19 |
20 |
21 | #textField(objectName="user", property="lastname", label="Last Name")# 22 |
23 |
24 | 25 | #textField(objectName="user", property="email", label="Email Address")# 26 | #passwordField(objectName="user", property="password", label="Password")# 27 | #passwordField(objectName="user", property="passwordConfirmation", label="Confirm Password")# 28 | 29 | #checkBox(objectName="user", property="terms", label="I agree to the terms and conditions")# 30 | 31 | #submitTag(value="Create Account", class="mt-4 btn btn-success")# 32 | 33 | #panelEnd()# 34 |
35 |
36 | 37 | #endFormTag()# 38 | 39 |
40 | -------------------------------------------------------------------------------- /views/wheels/layout.cfm: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | This is a view file that CFWheels uses internally. 4 | Do not delete this file or its containing folder. 5 | */ 6 | include "../../wheels/public/layout.cfm"; 7 | 8 | -------------------------------------------------------------------------------- /views/wheels/wheels.cfm: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | This is a view file that CFWheels uses internally. 4 | Do not delete this file or its containing folder. 5 | */ 6 | include "../../wheels/public/wheels.cfm"; 7 | 8 | -------------------------------------------------------------------------------- /wheels/Controller.cfc: -------------------------------------------------------------------------------- 1 | component output="false" displayName="Controller" { 2 | 3 | include "controller/functions.cfm"; 4 | include "global/functions.cfm"; 5 | include "view/functions.cfm"; 6 | include "plugins/standalone/injection.cfm"; 7 | if ( 8 | IsDefined("application") && StructKeyExists(application, "wheels") && StructKeyExists( 9 | application.wheels, 10 | "viewPath" 11 | ) 12 | ) { 13 | include "../#application.wheels.viewPath#/helpers.cfm"; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /wheels/Dispatch.cfc: -------------------------------------------------------------------------------- 1 | component output="false" { 2 | 3 | include "dispatch/functions.cfm"; 4 | include "global/functions.cfm"; 5 | include "plugins/standalone/injection.cfm"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /wheels/Mapper.cfc: -------------------------------------------------------------------------------- 1 | component output="false" { 2 | 3 | variables.$wheelsInclude = "cfml,internal,util"; 4 | include "mapper/functions.cfm"; 5 | include "global/functions.cfm"; 6 | include "plugins/standalone/injection.cfm"; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /wheels/Migrator.cfc: -------------------------------------------------------------------------------- 1 | component output="false" { 2 | 3 | include "migrator/functions.cfm"; 4 | include "global/functions.cfm"; 5 | include "plugins/standalone/injection.cfm"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /wheels/Model.cfc: -------------------------------------------------------------------------------- 1 | component output="false" displayName="Model" { 2 | 3 | include "model/functions.cfm"; 4 | include "global/functions.cfm"; 5 | include "plugins/standalone/injection.cfm"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /wheels/Plugins.cfc: -------------------------------------------------------------------------------- 1 | component output="false" { 2 | 3 | include "plugins/functions.cfm"; 4 | include "global/functions.cfm"; 5 | 6 | } 7 | -------------------------------------------------------------------------------- /wheels/Public.cfc: -------------------------------------------------------------------------------- 1 | component output="false" displayName="Internal GUI" { 2 | 3 | include "public/initialization.cfm"; 4 | include "public/includes.cfm"; 5 | 6 | } 7 | -------------------------------------------------------------------------------- /wheels/Test.cfc: -------------------------------------------------------------------------------- 1 | component output="false" displayName="Test" { 2 | 3 | include "test/functions.cfm"; 4 | include "global/functions.cfm"; 5 | include "plugins/standalone/injection.cfm"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /wheels/controller/appfunctions.cfm: -------------------------------------------------------------------------------- 1 | 2 | if (StructKeyExists(server, "lucee")) { 3 | include "caching.cfm"; 4 | include "filters.cfm"; 5 | include "flash.cfm"; 6 | include "initialization.cfm"; 7 | include "layouts.cfm"; 8 | include "miscellaneous.cfm"; 9 | include "processing.cfm"; 10 | include "provides.cfm"; 11 | include "redirection.cfm"; 12 | include "rendering.cfm"; 13 | include "verifies.cfm"; 14 | } else { 15 | include "wheels/controller/caching.cfm"; 16 | include "wheels/controller/filters.cfm"; 17 | include "wheels/controller/flash.cfm"; 18 | include "wheels/controller/initialization.cfm"; 19 | include "wheels/controller/layouts.cfm"; 20 | include "wheels/controller/miscellaneous.cfm"; 21 | include "wheels/controller/processing.cfm"; 22 | include "wheels/controller/provides.cfm"; 23 | include "wheels/controller/redirection.cfm"; 24 | include "wheels/controller/rendering.cfm"; 25 | include "wheels/controller/verifies.cfm"; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /wheels/controller/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "caching.cfm"; 3 | include "csrf.cfm"; 4 | include "filters.cfm"; 5 | include "flash.cfm"; 6 | include "initialization.cfm"; 7 | include "layouts.cfm"; 8 | include "miscellaneous.cfm"; 9 | include "processing.cfm"; 10 | include "provides.cfm"; 11 | include "redirection.cfm"; 12 | include "rendering.cfm"; 13 | include "verifies.cfm"; 14 | 15 | -------------------------------------------------------------------------------- /wheels/events/onabort.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onAbort(required targetpage) { 3 | $restoreTestRunnerApplicationScope(); 4 | $include(template = "#application.wheels.eventPath#/onabort.cfm"); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /wheels/events/onapplicationend.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onApplicationEnd(required struct applicationScope) { 3 | $include( 4 | template = "#arguments.applicationScope.wheels.eventPath#/onapplicationend.cfm", 5 | argumentCollection = arguments 6 | ); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /wheels/events/onmissingtemplate.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onMissingTemplate(required targetpage) { 3 | local.lockName = "reloadLock" & application.applicationName; 4 | $simpleLock( 5 | name = local.lockName, 6 | execute = "$runOnMissingTemplate", 7 | executeArgs = arguments, 8 | type = "readOnly", 9 | timeout = 180 10 | ); 11 | } 12 | 13 | public void function $runOnMissingTemplate(required targetpage) { 14 | if (!application.wheels.showErrorInformation) { 15 | $header(statusCode = 404, statustext = "Not Found"); 16 | } 17 | $includeAndOutput(template = "#application.wheels.eventPath#/onmissingtemplate.cfm"); 18 | abort; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /wheels/events/onrequest.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onRequest(required targetpage) { 3 | lock name="reloadLock#application.applicationName#" type="readOnly" timeout="180" { 4 | include "#arguments.targetpage#"; 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /wheels/events/onrequestend.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onRequestEnd(required targetpage) { 3 | local.lockName = "reloadLock" & application.applicationName; 4 | $simpleLock( 5 | name = local.lockName, 6 | execute = "$runOnRequestEnd", 7 | executeArgs = arguments, 8 | type = "readOnly", 9 | timeout = 180 10 | ); 11 | if ( 12 | application.wheels.showDebugInformation && StructKeyExists(request.wheels, "showDebugInformation") && request.wheels.showDebugInformation 13 | ) { 14 | $includeAndOutput(template = "wheels/events/onrequestend/debug.cfm"); 15 | } 16 | } 17 | 18 | public void function $runOnRequestEnd(required targetpage) { 19 | if (application.wheels.showDebugInformation) { 20 | $debugPoint("requestEnd"); 21 | } 22 | $restoreTestRunnerApplicationScope(); 23 | $include(template = "#application.wheels.eventPath#/onrequestend.cfm"); 24 | if (application.wheels.showDebugInformation) { 25 | $debugPoint("requestEnd,total"); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /wheels/events/onsessionend.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onSessionEnd(required sessionScope, required applicationScope) { 3 | local.lockName = "reloadLock" & arguments.applicationScope.applicationName; 4 | $simpleLock( 5 | name = local.lockName, 6 | execute = "$runOnSessionEnd", 7 | executeArgs = arguments, 8 | type = "readOnly", 9 | timeout = 180 10 | ); 11 | } 12 | 13 | public void function $runOnSessionEnd(required sessionScope, required applicationScope) { 14 | $include(template = "#arguments.applicationScope.wheels.eventPath#/onsessionend.cfm", argumentCollection = arguments); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /wheels/events/onsessionstart.cfm: -------------------------------------------------------------------------------- 1 | 2 | public void function onSessionStart() { 3 | local.lockName = "reloadLock" & application.applicationName; 4 | 5 | // Fix for shared application name (issue 359). 6 | if (!StructKeyExists(application, "wheels") || !StructKeyExists(application.wheels, "eventpath")) { 7 | $simpleLock( 8 | name = local.lockName, 9 | execute = "onApplicationStart", 10 | type = "exclusive", 11 | timeout = 180 12 | ); 13 | } 14 | 15 | $simpleLock( 16 | name = local.lockName, 17 | execute = "$runOnSessionStart", 18 | type = "readOnly", 19 | timeout = 180 20 | ); 21 | } 22 | 23 | public void function $runOnSessionStart() { 24 | $initializeRequestScope(); 25 | $include(template = "#application.wheels.eventPath#/onsessionstart.cfm"); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /wheels/global/appfunctions.cfm: -------------------------------------------------------------------------------- 1 | 2 | if (StructKeyExists(server, "lucee")) { 3 | include "cfml.cfm"; 4 | include "internal.cfm"; 5 | include "misc.cfm"; 6 | include "util.cfm"; 7 | include "../../global/functions.cfm"; 8 | } else { 9 | include "wheels/global/cfml.cfm"; 10 | include "wheels/global/internal.cfm"; 11 | include "wheels/global/misc.cfm"; 12 | include "wheels/global/util.cfm"; 13 | include "global/functions.cfm"; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /wheels/global/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | if (!StructKeyExists(variables, "$wheelsInclude") || ListFind(variables.$wheelsInclude, "cfml")) { 3 | include "cfml.cfm"; 4 | } 5 | if (!StructKeyExists(variables, "$wheelsInclude") || ListFind(variables.$wheelsInclude, "internal")) { 6 | include "internal.cfm"; 7 | } 8 | if (!StructKeyExists(variables, "$wheelsInclude") || ListFind(variables.$wheelsInclude, "misc")) { 9 | include "misc.cfm"; 10 | } 11 | if (!StructKeyExists(variables, "$wheelsInclude") || ListFind(variables.$wheelsInclude, "util")) { 12 | include "util.cfm"; 13 | } 14 | include "../../global/functions.cfm"; 15 | 16 | -------------------------------------------------------------------------------- /wheels/index.cfm: -------------------------------------------------------------------------------- 1 | 2 | 6 | #application.wheels.dispatch.$request()# -------------------------------------------------------------------------------- /wheels/mapper/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "initialization.cfm"; 3 | include "mapping.cfm"; 4 | include "matching.cfm"; 5 | include "resources.cfm"; 6 | include "scoping.cfm"; 7 | include "utilities.cfm"; 8 | 9 | -------------------------------------------------------------------------------- /wheels/mapper/initialization.cfm: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Internal function. 4 | */ 5 | public struct function $init(boolean restful = true, boolean methods = arguments.restful, boolean mapFormat = true) { 6 | // Set up control variables. 7 | variables.scopeStack = []; 8 | variables.restful = arguments.restful; 9 | variables.methods = arguments.restful || arguments.methods; 10 | variables.mapFormat = arguments.mapFormat; 11 | 12 | // Set up default variable constraints. 13 | variables.constraints = {}; 14 | variables.constraints.format = "\w+"; 15 | variables.constraints.controller = "[^\/]+"; 16 | 17 | // Set up constraint for globbed routes. 18 | variables.constraints["\*\w+"] = ".+"; 19 | 20 | return this; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /wheels/migrator/Base.cfc: -------------------------------------------------------------------------------- 1 | component { 2 | 3 | include "basefunctions.cfm"; 4 | 5 | } 6 | -------------------------------------------------------------------------------- /wheels/migrator/ViewDefinition.cfc: -------------------------------------------------------------------------------- 1 | component extends="Base" { 2 | 3 | public any function init(required any adapter, required string name) { 4 | local.args = "adapter,name,selectSql"; 5 | this.selectSql = ""; 6 | local.iEnd = ListLen(local.args); 7 | for (local.i = 1; local.i <= local.iEnd; local.i++) { 8 | local.argumentName = ListGetAt(local.args, local.i); 9 | if (StructKeyExists(arguments, local.argumentName)) { 10 | this[local.argumentName] = arguments[local.argumentName]; 11 | } 12 | } 13 | return this; 14 | } 15 | 16 | /** 17 | * Select statement to build view. 18 | */ 19 | public any function selectStatement(required string sql) { 20 | this.selectSql = arguments.sql; 21 | return this; 22 | } 23 | 24 | /** 25 | * Creates the table in the database. 26 | */ 27 | public void function create() { 28 | $execute(this.adapter.createView(name = this.name, sql = this.selectSql)); 29 | announce("Created view #objectCase(this.name)#"); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /wheels/migrator/templates/announce.cfc: -------------------------------------------------------------------------------- 1 | component extends="[extends]" hint="[description]" { 2 | 3 | function up() { 4 | announce(''); 5 | } 6 | 7 | function down() { 8 | announce(''); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /wheels/migrator/templates/blank.cfc: -------------------------------------------------------------------------------- 1 | component extends="[extends]" hint="[description]" { 2 | 3 | function up() { 4 | transaction { 5 | try { 6 | // your code goes here 7 | } catch (any e) { 8 | local.exception = e; 9 | } 10 | 11 | if (StructKeyExists(local, "exception")) { 12 | transaction action="rollback"; 13 | Throw( 14 | errorCode = "1", 15 | detail = local.exception.detail, 16 | message = local.exception.message, 17 | type = "any" 18 | ); 19 | } else { 20 | transaction action="commit"; 21 | } 22 | } 23 | } 24 | 25 | function down() { 26 | transaction { 27 | try { 28 | // your code goes here 29 | } catch (any e) { 30 | local.exception = e; 31 | } 32 | 33 | if (StructKeyExists(local, "exception")) { 34 | transaction action="rollback"; 35 | Throw( 36 | errorCode = "1", 37 | detail = local.exception.detail, 38 | message = local.exception.message, 39 | type = "any" 40 | ); 41 | } else { 42 | transaction action="commit"; 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /wheels/migrator/templates/execute.cfc: -------------------------------------------------------------------------------- 1 | component extends="[extends]" hint="[description]" { 2 | 3 | function up() { 4 | transaction { 5 | try { 6 | execute(''); 7 | } catch (any e) { 8 | local.exception = e; 9 | } 10 | 11 | if (StructKeyExists(local, "exception")) { 12 | transaction action="rollback"; 13 | Throw( 14 | errorCode = "1", 15 | detail = local.exception.detail, 16 | message = local.exception.message, 17 | type = "any" 18 | ); 19 | } else { 20 | transaction action="commit"; 21 | } 22 | } 23 | } 24 | 25 | function down() { 26 | transaction { 27 | try { 28 | execute(''); 29 | } catch (any e) { 30 | local.exception = e; 31 | } 32 | 33 | if (StructKeyExists(local, "exception")) { 34 | transaction action="rollback"; 35 | Throw( 36 | errorCode = "1", 37 | detail = local.exception.detail, 38 | message = local.exception.message, 39 | type = "any" 40 | ); 41 | } else { 42 | transaction action="commit"; 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /wheels/migrator/templates/remove-index.cfc: -------------------------------------------------------------------------------- 1 | /* 2 | |----------------------------------------------------------------------------| 3 | | Parameter | Required | Type | Default | Description | 4 | |----------------------------------------------------------------------------| 5 | | table | Yes | string | | table name | 6 | | indexName | Yes | string | | name of the index to remove | 7 | |----------------------------------------------------------------------------| 8 | 9 | EXAMPLE: 10 | removeIndex(table='members',indexName='members_username'); 11 | */ 12 | component extends="[extends]" hint="[description]" { 13 | 14 | function up() { 15 | transaction { 16 | try { 17 | removeIndex(table = 'tableName', indexName = ''); 18 | } catch (any e) { 19 | local.exception = e; 20 | } 21 | 22 | if (StructKeyExists(local, "exception")) { 23 | transaction action="rollback"; 24 | Throw( 25 | errorCode = "1", 26 | detail = local.exception.detail, 27 | message = local.exception.message, 28 | type = "any" 29 | ); 30 | } else { 31 | transaction action="commit"; 32 | } 33 | } 34 | } 35 | 36 | function down() { 37 | transaction { 38 | try { 39 | addIndex(table = 'tableName', columnNames = 'columnName', unique = true); 40 | } catch (any e) { 41 | local.exception = e; 42 | } 43 | 44 | if (StructKeyExists(local, "exception")) { 45 | transaction action="rollback"; 46 | Throw( 47 | errorCode = "1", 48 | detail = local.exception.detail, 49 | message = local.exception.message, 50 | type = "any" 51 | ); 52 | } else { 53 | transaction action="commit"; 54 | } 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /wheels/migrator/templates/remove-table.cfc: -------------------------------------------------------------------------------- 1 | /* 2 | |----------------------------------------------------------------------------------------------| 3 | | Parameter | Required | Type | Default | Description | 4 | |----------------------------------------------------------------------------------------------| 5 | | name | Yes | string | | table name to drop | 6 | |----------------------------------------------------------------------------------------------| 7 | 8 | EXAMPLE: 9 | dropTable(name='employees'); 10 | */ 11 | component extends="[extends]" hint="[description]" { 12 | 13 | function up() { 14 | transaction { 15 | try { 16 | dropTable(name = 'tableName'); 17 | } catch (any e) { 18 | local.exception = e; 19 | } 20 | 21 | if (StructKeyExists(local, "exception")) { 22 | transaction action="rollback"; 23 | Throw( 24 | errorCode = "1", 25 | detail = local.exception.detail, 26 | message = local.exception.message, 27 | type = "any" 28 | ); 29 | } else { 30 | transaction action="commit"; 31 | } 32 | } 33 | } 34 | 35 | function down() { 36 | transaction { 37 | try { 38 | t = createTable(name = 'tableName'); 39 | t.timestamps(); 40 | t.create(); 41 | } catch (any e) { 42 | local.exception = e; 43 | } 44 | 45 | if (StructKeyExists(local, "exception")) { 46 | transaction action="rollback"; 47 | Throw( 48 | errorCode = "1", 49 | detail = local.exception.detail, 50 | message = local.exception.message, 51 | type = "any" 52 | ); 53 | } else { 54 | transaction action="commit"; 55 | } 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /wheels/model/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "associations.cfm"; 3 | include "calculations.cfm"; 4 | include "callbacks.cfm"; 5 | include "create.cfm"; 6 | include "delete.cfm"; 7 | include "errors.cfm"; 8 | include "initialization.cfm"; 9 | include "miscellaneous.cfm"; 10 | include "nestedproperties.cfm"; 11 | include "onmissingmethod.cfm"; 12 | include "properties.cfm"; 13 | include "read.cfm"; 14 | include "serialize.cfm"; 15 | include "sql.cfm"; 16 | include "transactions.cfm"; 17 | include "update.cfm"; 18 | include "validations.cfm"; 19 | 20 | -------------------------------------------------------------------------------- /wheels/plugins/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "initialization.cfm"; 3 | 4 | -------------------------------------------------------------------------------- /wheels/plugins/standalone/injection.cfm: -------------------------------------------------------------------------------- 1 | 2 | // We use $wheels here since these variables get placed in the variables scope of all objects. 3 | // This way we sure they don't clash with other Wheels variables or any variables the developer may set. 4 | if (IsDefined("application") && StructKeyExists(application, "$wheels")) { 5 | $wheels.appKey = "$wheels"; 6 | } else { 7 | $wheels.appKey = "wheels"; 8 | } 9 | 10 | if (IsDefined("application") && !StructIsEmpty(application[$wheels.appKey].mixins)) { 11 | $wheels.metaData = GetMetadata(this); 12 | if (StructKeyExists($wheels.metaData, "displayName")) { 13 | $wheels.className = $wheels.metaData.displayName; 14 | } else { 15 | $wheels.className = Reverse(SpanExcluding(Reverse($wheels.metaData.name), ".")); 16 | } 17 | if (StructKeyExists(application[$wheels.appKey].mixins, $wheels.className)) { 18 | if (!StructKeyExists(variables, "core")) { 19 | if (application[$wheels.appKey].serverName == "Railo") { 20 | // this is to work around a railo bug (https://jira.jboss.org/browse/RAILO-936) 21 | // NB, fixed in Railo 3.2.0, so assume this is fixed in all lucee versions 22 | variables.core = Duplicate(variables); 23 | } else { 24 | variables.core = {}; 25 | StructAppend(variables.core, variables); 26 | StructDelete(variables.core, "$wheels"); 27 | } 28 | } 29 | StructAppend(variables, application[$wheels.appKey].mixins[$wheels.className], true); 30 | } 31 | 32 | // Get rid of any extra data created in the variables scope. 33 | if (StructKeyExists(variables, "$wheels")) { 34 | StructDelete(variables, "$wheels"); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /wheels/public/assets/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /wheels/public/docs/core.cfm: -------------------------------------------------------------------------------- 1 | 2 | // Core API embedded documentation 3 | 4 | param name="request.wheels.params.type" default="core"; 5 | param name="request.wheels.params.format" default="html"; 6 | 7 | if(structKeyExists(application.wheels, "docs")){ 8 | 9 | docs = application.wheels.docs; 10 | 11 | } else { 12 | 13 | documentScope = []; 14 | 15 | // Plugins First, as they can potentially hijack an internal function 16 | if (application.wheels.enablePluginsComponent) { 17 | for (local.plugin in application.wheels.plugins) { 18 | ArrayAppend(documentScope, {"name" = local.plugin, "scope" = application.wheels.plugins[local.plugin]}); 19 | } 20 | } 21 | 22 | ArrayAppend(documentScope, {"name" = "controller", "scope" = CreateObject("component", "app.controllers.Controller")}); 23 | ArrayAppend(documentScope, {"name" = "model", "scope" = CreateObject("component", "app.models.Model")}); 24 | ArrayAppend(documentScope, {"name" = "mapper", "scope" = application.wheels.mapper}); 25 | if (application.wheels.enablePluginsComponent) { 26 | ArrayAppend(documentScope, {"name" = "migrator", "scope" = application.wheels.migrator}); 27 | ArrayAppend( 28 | documentScope, 29 | {"name" = "migration", "scope" = CreateObject("component", "app.wheels.migrator.Migration")} 30 | ); 31 | ArrayAppend( 32 | documentScope, 33 | {"name" = "tabledefinition", "scope" = CreateObject("component", "app.wheels.migrator.TableDefinition")} 34 | ); 35 | } 36 | // Array of functions to ignore 37 | ignore = ["config", "init"]; 38 | 39 | // Populate the main documentation 40 | docs = $returnInternalDocumentation(documentScope, ignore); 41 | 42 | application.wheels.docs = docs; 43 | } 44 | 45 | include "layouts/#request.wheels.params.format#.cfm"; 46 | 47 | -------------------------------------------------------------------------------- /wheels/public/docs/layouts/json.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | #SerializeJSON(docs)# 4 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/addformat.txt: -------------------------------------------------------------------------------- 1 | // Add the `js` format 2 | addFormat(extension="js", mimeType="text/javascript"); 3 | 4 | // Add the `ppt` and `pptx` formats 5 | addFormat(extension="ppt", mimeType="application/vnd.ms-powerpoint"); 6 | addFormat(extension="pptx", mimeType="application/vnd.ms-powerpoint"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/authenticitytokenfield.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | #authenticityTokenField()# 4 | 5 | 6 | 7 |
8 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/autolink.txt: -------------------------------------------------------------------------------- 1 | 2 | #autoLink("Download CFWheels from http://cfwheels.org/download")# 3 | 4 | 5 | #autoLink("Email us at info@cfwheels.org")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/buttontag.txt: -------------------------------------------------------------------------------- 1 | 2 | #startFormTag(action="something")# 3 | 4 | #buttonTag(content="Submit this form", value="save")# 5 | #endFormTag()# 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/buttonto.txt: -------------------------------------------------------------------------------- 1 | #buttonTo(text="Delete Account", action="perFormDelete", disable="Wait...")# 2 | 3 | 4 | #buttonTo(text="Edit", action="edit", inputId="edit-button", inputClass="edit-button-class")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/caches.txt: -------------------------------------------------------------------------------- 1 | // Cache the `termsOfUse` action. 2 | caches("termsOfUse"); 3 | 4 | // Cache the `termsOfUse` action for 30 minutes. 5 | caches(actions="browseByUser, browseByTitle", time=30); 6 | 7 | // Cache the `termsOfUse` and `codeOfConduct` actions, including their filters. 8 | caches(actions="termsOfUse, codeOfConduct", static=true); 9 | 10 | // Cache content separately based on region. 11 | caches(action="home", key="request.region"); 12 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/capitalize.txt: -------------------------------------------------------------------------------- 1 | 2 | #capitalize("wheels is a framework")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/checkbox.txt: -------------------------------------------------------------------------------- 1 | 2 | #checkBox(objectName="photo", property="isPublic", label="Display this photo publicly.")# 3 | 4 | 5 | 6 |
7 |

#user.photos[i].title#:

8 |
9 | #checkBox(objectName="user", association="photos", position=i, property="isPublic", label="Display this photo publicly.")# 10 |
11 |
12 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/checkboxtag.txt: -------------------------------------------------------------------------------- 1 | 2 | #checkBoxTag(name="subscribe", value="true", label="Subscribe to our newsletter", checked=false)# 3 | 4 | 5 | // Controller code 6 | pizza = model("pizza").findByKey(session.pizzaId); 7 | selectedToppings = pizza.toppings(); 8 | toppings = model("topping").findAll(order="name"); 9 | 10 | 11 |
12 | Toppings 13 | 14 | #checkBoxTag(name="toppings", value="true", label=toppings.name, checked=YesNoFormat(ListFind(ValueList(selectedToppings.id), toppings.id))# 15 | 16 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/columndataforproperty.txt: -------------------------------------------------------------------------------- 1 | // Get an object, set a value and then see if the property exists 2 | employee = model("employee").new(); 3 | 4 | // returns column struct 5 | employee.columnDataForProperty("firstName"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/columnforproperty.txt: -------------------------------------------------------------------------------- 1 | // Get an object, set a value and then see if the property exists 2 | employee = model("employee").new(); 3 | 4 | // returns column name, in this case "firstname" if the convention is used 5 | employee.columnForProperty("firstName"); 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/columnnames.txt: -------------------------------------------------------------------------------- 1 | // Get a list of all the column names in the table mapped to the `author` model 2 | columns = model("author").columnNames(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/columns.txt: -------------------------------------------------------------------------------- 1 | // Get the columns names in the order they are in the database 2 | employee = model("employee").columns(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/compareto.txt: -------------------------------------------------------------------------------- 1 | // Load a user requested in the URL/form and restrict access if it doesn't match the user stored in the session 2 | user = model("user").findByKey(params.key); 3 | if(!user.compareTo(session.user)){ 4 | renderView(action="accessDenied"); 5 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/contentfor.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 |

My Sidebar Text

4 |
5 | 6 | 7 | 8 | 9 | 10 | My Site 11 | 12 | 13 | 14 | #includeContent("sidebar")# 15 | #includeContent()# 16 | 17 | 18 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/contentforlayout.txt: -------------------------------------------------------------------------------- 1 | 2 | #contentForLayout()# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/controller.txt: -------------------------------------------------------------------------------- 1 | testController = controller("users", params); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/csrfmetatags.txt: -------------------------------------------------------------------------------- 1 | 2 | #csrfMetaTags()# 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/cycle.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
NamePhone
#employees.name##employees.phone#
18 | 19 | 20 | 21 |
22 |
    23 | 24 | rank = cycle(values="president,vice-president,director,manager,specialist,intern", name="position")> 25 |
  • #categories.categoryName#
  • 26 | resetCycle("emphasis")> 27 |
    28 |
29 |
30 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/dateselect.txt: -------------------------------------------------------------------------------- 1 | 2 | #dateSelect(objectName="user", property="dateOfBirth")# 3 | 4 | 5 | #dateSelect(objectName="order", property="expirationDate", order="month,year")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/dateselecttags.txt: -------------------------------------------------------------------------------- 1 | 2 | #dateSelectTags(name="dateStart", selected=params.dateStart)# 3 | 4 | 5 | #dateSelectTags(name="expiration", selected=params.expiration, order="month,year")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/datetimeselect.txt: -------------------------------------------------------------------------------- 1 | 2 | #dateTimeSelect(objectName="article", property="publishedAt")# 3 | 4 | 5 | #dateTimeSelect(objectName="appointment", property="dateTimeStart", dateOrder="month,day", timeOrder="hour,minute")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/datetimeselecttags.txt: -------------------------------------------------------------------------------- 1 | 2 | #dateTimeSelectTags(name="dateTimeStart", selected=params.dateTimeStart)# 3 | 4 | 5 | #dateTimeSelectTags(name="dateTimeStart", selected=params.dateTimeStart, dateOrder="month,day", timeOrder="hour,minute")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/dayselecttag.txt: -------------------------------------------------------------------------------- 1 | 2 | #daySelectTag(name="dayOfWeek", selected=params.dayOfWeek)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/deobfuscateparam.txt: -------------------------------------------------------------------------------- 1 | // Get the original value from an obfuscated one 2 | originalValue = deobfuscateParam("b7ab9a50"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/distanceoftimeinwords.txt: -------------------------------------------------------------------------------- 1 | // Controller code. 2 | rightNow = Now(); 3 | aWhileAgo = DateAdd("d", -30, rightNow); 4 | 5 | // View code. 6 | 7 | #distanceOfTimeInWords(aWhileAgo, rightNow)# 8 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/endformtag.txt: -------------------------------------------------------------------------------- 1 | 2 | #startFormTag(action="create")# 3 | 4 | #endFormTag()# 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/excerpt.txt: -------------------------------------------------------------------------------- 1 | 2 | #excerpt(text="CFWheels is a Rails-like MVC framework for Adobe ColdFusion and Lucee", phrase="framework", radius=5)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/filefield.txt: -------------------------------------------------------------------------------- 1 | 2 | #fileField(label="Photo", objectName="photo", property="imageFile")# 3 | 4 | 5 | 6 |
7 | Screenshots 8 | 9 | #fileField(label="File ##i#", objectName="site", association="screenshots", position=i, property="file")# 10 | #textField(label="Caption ##i#", objectName="site", association="screenshots", position=i, property="caption")# 11 | 12 |
13 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/filefieldtag.txt: -------------------------------------------------------------------------------- 1 | 2 | #fileFieldTag(label="Photo", name="photo", value=params.photo)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/filterchain.txt: -------------------------------------------------------------------------------- 1 | // Get filter chain. 2 | myFilterChain = filterChain(); 3 | 4 | // Get filter chain for after filters only. 5 | myFilterChain = filterChain(type="after"); 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/filters.txt: -------------------------------------------------------------------------------- 1 | // Always execute `restrictAccess` before all actions in this controller. 2 | filters("restrictAccess"); 3 | 4 | // Always execute `isLoggedIn` and `checkIPAddress` (in that order) before all actions in this controller, except the `home` and `login` actions. 5 | filters(through="isLoggedIn, checkIPAddress", except="home, login"); 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flash.txt: -------------------------------------------------------------------------------- 1 | // Get the current value of notice in the Flash 2 | notice = flash("notice"); 3 | 4 | // Get the entire Flash as a struct 5 | flashContents = flash(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashclear.txt: -------------------------------------------------------------------------------- 1 | flashClear(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashcount.txt: -------------------------------------------------------------------------------- 1 | count = flashCount(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashdelete.txt: -------------------------------------------------------------------------------- 1 | flashDelete(key="errorMessage"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashinsert.txt: -------------------------------------------------------------------------------- 1 | flashInsert(msg="It Worked!"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashisempty.txt: -------------------------------------------------------------------------------- 1 | empty = flashIsEmpty(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashkeep.txt: -------------------------------------------------------------------------------- 1 | // Keep the entire Flash for the next request 2 | flashKeep(); 3 | 4 | // Keep the "error" key in the Flash for the next request 5 | flashKeep("error"); 6 | 7 | // Keep both the "error" and "success" keys in the Flash for the next request 8 | flashKeep("error,success"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashkeyexists.txt: -------------------------------------------------------------------------------- 1 | errorExists = flashKeyExists("error"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/flashmessages.txt: -------------------------------------------------------------------------------- 1 | // In the controller action 2 | flashInsert(success="Your post was successfully submitted."); 3 | flashInsert(alert="Don't forget to tweet about this post!"); 4 | flashInsert(error="This is an error message."); 5 | 6 | 7 | #flashMessages()# 8 | 9 | 10 |
11 |

12 | Don't forget to tweet about this post! 13 |

14 |

15 | This is an error message. 16 |

17 |

18 | Your post was successfully submitted. 19 |

20 |
21 | 22 | 23 | 24 | #flashMessages(key="success")# 25 | 26 | 27 |
28 |

29 | Your post was successfully submitted. 30 |

31 |
32 | 33 | 34 | 35 | #flashMessages(keys="success,alert")# 36 | 37 | 38 |
39 |

40 | Your post was successfully submitted. 41 |

42 |

43 | Don't forget to tweet about this post! 44 |

45 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/get.txt: -------------------------------------------------------------------------------- 1 | // Get the current value for the `tableNamePrefix` Wheels setting 2 | setting = get("tableNamePrefix"); 3 | 4 | // Get the default for the `message` argument of the `validatesConfirmationOf` method 5 | setting = get(functionName="validatesConfirmationOf", name="message"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/hasmanycheckbox.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | #hasManyCheckBox( 4 | label=authors.fullName, 5 | objectName="book", 6 | association="bookAuthors", 7 | keys="#book.key()#,#authors.id#" 8 | )# 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/hasmanyradiobutton.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | #hasManyRadioButton( 4 | label=addresses.title, 5 | objectName="author", 6 | association="authorsDefaultAddresses", 7 | keys="#author.key()#,#addresses.id#" 8 | )# 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/hiddenfield.txt: -------------------------------------------------------------------------------- 1 | 2 | #hiddenField(objectName="user", property="id")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/hiddenfieldtag.txt: -------------------------------------------------------------------------------- 1 | 2 | #hiddenFieldTag(name="userId", value=user.id)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/highlight.txt: -------------------------------------------------------------------------------- 1 | 2 | #highlight(text="You searched for: CFWheels", phrases="CFWheels")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/hourselecttag.txt: -------------------------------------------------------------------------------- 1 | 2 | #hourSelectTag(name="hourOfMeeting", selected=params.hourOfMeeting)# 3 | 4 | 5 | #hourSelectTag(name="hourOfMeeting", selected=params.hourOfMeeting, twelveHour=true)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/humanize.txt: -------------------------------------------------------------------------------- 1 | 2 | #humanize("wheelsIsAFramework")# 3 | 4 | 5 | #humanize("wheelsIsACfmlFramework", "CFML")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/hyphenize.txt: -------------------------------------------------------------------------------- 1 | 2 | #hyphenize("myBlogPost")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/imagetag.txt: -------------------------------------------------------------------------------- 1 | 2 | #imageTag("logo.png")# 3 | 4 | 5 | #imageTag(source="http://cfwheels.org/images/logo.png", alt="ColdFusion on Wheels")# 6 | 7 | 8 | #imageTag(source="logo.png", class="logo")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/includecontent.txt: -------------------------------------------------------------------------------- 1 | 2 | contentFor(head=''); 3 | contentFor(head=''); 4 | 5 | // In `views/layout.cfm` 6 | 7 | 8 | My Site 9 | #includeContent("head")# 10 | 11 | 12 | 13 | #includeContent()# 14 | 15 | 16 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/includedinobject.txt: -------------------------------------------------------------------------------- 1 | // Check to see if the customer is subscribed to the Swimsuit Edition. Note that the order of the `keys` argument should match the order of the `customerid` and `publicationid` columns in the `subscriptions` join table 2 | if(!includedInObject(objectName="customer", association="subscriptions", keys="#customer.key()#,#swimsuitEdition.id#")){ 3 | assignSalesman(customer); 4 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/includelayout.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
    5 | #includePartial(categories)# 6 |
7 |
8 |
9 | contentFor(sidebar=categoriesSidebar); 10 | 11 | 12 | #includeLayout("/layout.cfm")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/includepartial.txt: -------------------------------------------------------------------------------- 1 | 2 | // If we're in the "sessions" controller, CFWheels will include the file "views/sessions/_login.cfm". 3 | #includePartial("login")# 4 | 5 | // CFWheels will include the file "views/shared/_button.cfm". 6 | #includePartial(partial="/shared/button")# 7 | 8 | // If we're in the "posts" controller and the "posts" variable includes a query result set, CFWheels will loop through the record set and include the file "views/posts/_post.cfm" for each record. 9 | 10 | #includePartial(posts)# 11 | 12 | // We can also override the template file loaded for the example above. 13 | #includePartial(partial="/shared/post", query=posts)# 14 | 15 | // The same works when passing a model instance. 16 | #includePartial(post)# 17 | #includePartial(partial="/shared/post", object=post)# 18 | 19 | // The same works when passing an array of model objects. 20 | 21 | #includePartial(posts)# 22 | #includePartial(partial="/shared/post", objects=posts)# 23 | 24 | 25 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/isajax.txt: -------------------------------------------------------------------------------- 1 | requestIsAjax = isAjax(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/isget.txt: -------------------------------------------------------------------------------- 1 | requestIsGet = isGet(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/ispost.txt: -------------------------------------------------------------------------------- 1 | requestIsPost = isPost(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/issecure.txt: -------------------------------------------------------------------------------- 1 | // Redirect non-secure connections to the secure version 2 | if (!isSecure()) 3 | { 4 | redirectTo(protocol="https"); 5 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/javascriptincludetag.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #javaScriptIncludeTag("main")# 5 | 6 | 7 | #javaScriptIncludeTag("blog,accordion")# 8 | 9 | 10 | #javaScriptIncludeTag("https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js")# 11 | 12 | 13 | 14 | 15 | #javaScriptIncludeTag(source="tabs", head=true)# 16 | 17 | 18 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/linkto.txt: -------------------------------------------------------------------------------- 1 | #linkTo(text="Log Out", controller="account", action="logout")# 2 | 3 | 4 | 5 | #linkTo(text="Log Out", action="logout")# 6 | 7 | 8 | #linkTo(text="View Post", controller="blog", action="post", key=99)# 9 | 10 | 11 | #linkTo(text="View Settings", action="settings", params="show=all&sort=asc")# 12 | 13 | 14 | 15 | #linkTo(text="Joe's Profile", route="userProfile", userName="joe")# 16 | 17 | 18 | 19 | #linkTo(text="ColdFusion Framework", href="http://cfwheels.org/")# 20 | 21 | 22 | 23 | #linkTo(text="Delete Post", action="delete", key=99, class="delete", id="delete-99")# 24 | 25 | 26 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/mailto.txt: -------------------------------------------------------------------------------- 1 | #mailTo(emailAddress="webmaster@yourdomain.com", name="Contact our Webmaster")# 2 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/mimetypes.txt: -------------------------------------------------------------------------------- 1 | // Get the internally-stored MIME type for `xls` 2 | mimeType = mimeTypes("xls"); 3 | 4 | // Get the internally-stored MIME type for a dynamic value. Fall back to a MIME type of `text/plain` if it's not found 5 | mimeType = mimeTypes(extension=params.type, fallback="text/plain"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/minuteselecttag.txt: -------------------------------------------------------------------------------- 1 | // This "Tag" version of the function accepts a `name` and `selected` instead of binding to a model object 2 | 3 | #minuteSelectTag(name="minuteOfMeeting", value=params.minuteOfMeeting)# 4 | 5 | 6 | // Only show 15-minute intervals 7 | 8 | #minuteSelectTag(name="minuteOfMeeting", value=params.minuteOfMeeting, minuteStep=15)# 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/model.txt: -------------------------------------------------------------------------------- 1 | // The `model("author")` part of the code below gets a reference to the model from the application scope, and then the `findByKey` class level method is called on it 2 | authorObject = model("author").findByKey(1); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/monthselecttag.txt: -------------------------------------------------------------------------------- 1 | // This "Tag" version of the function accepts a `name` and `selected` instead of binding to a model object 2 | 3 | #monthSelectTag(name="monthOfBirthday", selected=params.monthOfBirthday)# 4 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/obfuscateparam.txt: -------------------------------------------------------------------------------- 1 | // Obfuscate the primary key value `99` 2 | newValue = obfuscateParam(99); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/onlyprovides.txt: -------------------------------------------------------------------------------- 1 | // This will only provide the `html` type and will ignore what was defined in the call to `provides()` in the `config()` function 2 | onlyProvides("html"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/pagination.txt: -------------------------------------------------------------------------------- 1 | allAuthors = model("author").findAll(page=1, perPage=25, order="lastName", handle="authorsData"); 2 | paginationData = pagination("authorsData"); 3 | 4 | #pagination().currentPage# 5 | #pagination().totalPages# 6 | #pagination().totalRecords# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/passwordfield.txt: -------------------------------------------------------------------------------- 1 | // Provide a `label` and the required `objectName` and `property` 2 | 3 | #passwordField(label="Password", objectName="user", property="password")# 4 | 5 | 6 | // Display fields for passwords provided by the `passwords` association and nested properties 7 |
8 | Passwords 9 | 10 | #passwordField(label="Password ##i#", objectName="user", association="passwords", position=i, property="password")# 11 | 12 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/passwordfieldtag.txt: -------------------------------------------------------------------------------- 1 | // Basic usage usually involves a `label`, `name`, and `value` 2 | 3 | #passwordFieldTag(label="Password", name="password", value=params.password)# 4 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/pluginnames.txt: -------------------------------------------------------------------------------- 1 | // Check if the Scaffold plugin is installed 2 | 3 | // do something cool 4 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/pluralize.txt: -------------------------------------------------------------------------------- 1 | // Pluralize a word, will result in "people" 2 | #pluralize("person")# 3 | 4 | // Pluralize based on the count passed in 5 | Your search returned #pluralize(word="person", count=users.RecordCount)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/provides.txt: -------------------------------------------------------------------------------- 1 | provides("html,xml,json"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/radiobutton.txt: -------------------------------------------------------------------------------- 1 | // Basic example view code. 2 | 3 |
4 | Gender 5 | #radioButton(objectName="user", property="gender", tagValue="m", label="Male")#
6 | #radioButton(objectName="user", property="gender", tagValue="f", label="Female")# 7 |
8 |
9 | 10 | // Shows radio buttons for selecting the genders for all committee members provided by the `members` association and nested properties. 11 | 12 | 13 |
14 |

#committee.members[i].fullName#:

15 |
16 | #radioButton(objectName="committee", association="members", position=i, property="gender", tagValue="m", label="Male")#
17 | #radioButton(objectName="committee", association="members", position=i, property="gender", tagValue="f", label="Female")# 18 |
19 |
20 |
21 |
22 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/radiobuttontag.txt: -------------------------------------------------------------------------------- 1 | // Basic usage usually involves a `label`, `name`, `value`, and `checked` value 2 | 3 |
4 | Gender 5 | #radioButtonTag(name="gender", value="m", label="Male", checked=true)#
6 | #radioButtonTag(name="gender", value="f", label="Female")# 7 |
8 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/redirectto.txt: -------------------------------------------------------------------------------- 1 | // Redirect to an action after successfully saving a user. 2 | if (user.save()) { 3 | redirectTo(action="saveSuccessful"); 4 | } 5 | 6 | // Redirect to a specific page on a secure server. 7 | redirectTo(controller="checkout", action="start", params="type=express", protocol="https"); 8 | 9 | // Redirect to a route specified in `config/routes.cfm` and pass in the screen name that the route takes. 10 | redirectTo(route="profile", screenName="Joe"); 11 | 12 | // Redirect back to the page the user came from. 13 | redirectTo(back=true); 14 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/rendernothing.txt: -------------------------------------------------------------------------------- 1 | // Render a blank white page to the client 2 | renderNothing(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/renderpartial.txt: -------------------------------------------------------------------------------- 1 | // Render the partial `_comment.cfm` located in the current controller's view folder 2 | renderPartial("comment"); 3 | 4 | // Render the partial at `views/shared/_comment.cfm` 5 | renderPartial("/shared/comment"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/rendertext.txt: -------------------------------------------------------------------------------- 1 | // Render just the text "Done!" to the client 2 | renderText("Done!"); 3 | 4 | // Render serialized product data to the client 5 | products = model("product").findAll(); 6 | renderText(SerializeJson(products)); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/renderview.txt: -------------------------------------------------------------------------------- 1 | // Render a view page for a different action within the same controller. 2 | renderView(action="edit"); 3 | 4 | // Render a view page for a different action within a different controller. 5 | renderView(controller="blog", action="new"); 6 | 7 | // Another way to render the blog/new template from within a different controller. 8 | renderView(template="/blog/new"); 9 | 10 | // Render the view page for the current action but without a layout and cache it for 60 minutes. 11 | renderView(layout=false, cache=60); 12 | 13 | // Load a layout from a different folder within `views`. 14 | renderView(layout="/layouts/blog"); 15 | 16 | // Don't render the view immediately but rather return and store in a variable for further processing. 17 | myView = renderView(returnAs="string"); 18 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/renderwith.txt: -------------------------------------------------------------------------------- 1 | // This will provide the formats defined in the `config()` function. 2 | products = model("product").findAll(); 3 | renderWith(products); 4 | 5 | // Provide a 403 status code for a json response (for example) 6 | msg={ 7 | "status" : "Error", 8 | "message": "Not Authenticated" 9 | } 10 | renderWith(data=msg, status=403) 11 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/resetcycle.txt: -------------------------------------------------------------------------------- 1 | // alternating row colors and shrinking emphasis 2 | 3 |
4 |
    5 | 6 | rank = cycle(values="president,vice-president,director,manager,specialist,intern", name="position")> 7 |
  • #categories.categoryName#
  • 8 | resetCycle("emphasis")> 9 |
    10 |
11 |
12 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/response.txt: -------------------------------------------------------------------------------- 1 | wheelsResponse = response(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/secondselecttag.txt: -------------------------------------------------------------------------------- 1 | 2 | #secondSelectTag(name="secondsToLaunch", selected=params.secondsToLaunch)# 3 | 4 | 5 | 6 | #secondSelectTag(name="secondsToLaunch", value=params.secondsToLaunch, secondStep=15)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/select.txt: -------------------------------------------------------------------------------- 1 | // Example 1: Basic `select` field with `label` and required `objectName` and `property` arguments 2 | // - Controller code 3 | authors = model("author").findAll(); 4 | 5 | 6 | #select(objectName="book", property="authorId", options=authors)# 7 | 8 | 12 | #select(objectName="book", property="authorId", options=authors, valueField="id", textField="authorfullname")# 13 | 14 | // Example 2: Shows `select` fields for selecting order statuses for all shipments provided by the `orders` association and nested properties 15 | // Controller code 16 | shipment = model("shipment").findByKey(key=params.key, where="shipments.statusId=#application.NEW_STATUS_ID#", include="order"); 17 | statuses = model("status").findAll(order="name"); 18 | 19 | 20 | 21 | #select(label="Order #shipments.orders[i].orderNum#", objectName="shipment", association="orders", position=i, property="statusId", options=statuses)# 22 | 23 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/selecttag.txt: -------------------------------------------------------------------------------- 1 | // Controller code 2 | cities = model("city").findAll()> 3 | 4 | 5 | #selectTag(name="cityId", options=cities)# 6 | 7 | 11 | #selectTag(name="cityId", options=cities, valueField="id", textField="name")# 12 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/sendemail.txt: -------------------------------------------------------------------------------- 1 | // Get a member and send a welcome email, passing in a few custom variables to the template 2 | newMember = model("member").findByKey(params.member.id); 3 | sendEmail( 4 | to=newMember.email, 5 | template="myemailtemplate", 6 | subject="Thank You for Becoming a Member", 7 | recipientName=newMember.name, 8 | startDate=newMember.startDate 9 | ); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/sendfile.txt: -------------------------------------------------------------------------------- 1 | // Send a PDF file to the user 2 | sendFile(file="wheels_tutorial_20081028_J657D6HX.pdf"); 3 | 4 | // Send the same file but give the user a different name in the browser dialog window 5 | sendFile(file="wheels_tutorial_20081028_J657D6HX.pdf", name="Tutorial.pdf"); 6 | 7 | // Send a file that is located outside of the web root 8 | sendFile(file="../../tutorials/wheels_tutorial_20081028_J657D6HX.pdf"); 9 | 10 | // Send a file that is located in ram:// 11 | sendFile(file="ram://wheels_tutorial_20081028_J657D6HX.pdf"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/set.txt: -------------------------------------------------------------------------------- 1 | // Example 1: Set the `URLRewriting` setting to `Partial`. 2 | set(URLRewriting="Partial"); 3 | 4 | // Example 2: Set default values for the arguments in the `buttonTo` view helper. This works for the majority of Wheels functions/arguments. 5 | set(functionName="buttonTo", onlyPath=true, host="", protocol="", port=0, text="", confirm="", image="", disable=""); 6 | 7 | // Example 3: Set the default values for a form helper to get the form marked up to your preferences. 8 | set(functionName="textField", labelPlacement="before", prependToLabel="
", append="
", appendToLabel="
"): 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/setfilterchain.txt: -------------------------------------------------------------------------------- 1 | // Set filter chain directly in an array. 2 | setFilterChain([ 3 | {through="restrictAccess"}, 4 | {through="isLoggedIn, checkIPAddress", except="home, login"}, 5 | {type="after", through="logConversion", only="thankYou"} 6 | ]); 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/setresponse.txt: -------------------------------------------------------------------------------- 1 | setResponse(newReponse); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/setverificationchain.txt: -------------------------------------------------------------------------------- 1 | // Set verification chain directly in an array. 2 | setVerificationChain([ 3 | {only="handleForm", post=true}, 4 | {only="edit", get=true, params="userId", paramsTypes="integer"}, 5 | {only="edit", get=true, params="userId", paramsTypes="integer", handler="index", error="Invalid userId"} 6 | ]); 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/simpleformat.txt: -------------------------------------------------------------------------------- 1 | 2 | #simpleFormat(post.bodyText)# 3 | 4 | 5 | 6 | I love this post! 7 | 8 | Here's why: 9 | * Short 10 | * Succinct 11 | * Awesome 12 | 13 | #simpleFormat(comment)# 14 | 15 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/singularize.txt: -------------------------------------------------------------------------------- 1 | // Singularize a word, will result in "language" 2 | #singularize("languages")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/startformtag.txt: -------------------------------------------------------------------------------- 1 | 2 | #startFormTag(action="create")# 3 | 4 | #endFormTag()# 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/striplinks.txt: -------------------------------------------------------------------------------- 1 | 2 | #stripLinks('Wheels is a framework for ColdFusion.')# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/striptags.txt: -------------------------------------------------------------------------------- 1 | 2 | #stripTags('Wheels is a framework for ColdFusion.')# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/stylesheetlinktag.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #styleSheetLinkTag("styles")# 5 | 6 | #styleSheetLinkTag("blog,comments")# 7 | 8 | #styleSheetLinkTag(sources="print", media="print")# 9 | 10 | #styleSheetLinkTag("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/cupertino/jquery-ui.css")# 11 | 12 | 13 | 14 | 15 | #styleSheetLinkTag(sources="tabs", head=true)# 16 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/submittag.txt: -------------------------------------------------------------------------------- 1 | #startFormTag(action="something")# 2 | 3 | #submitTag()# 4 | #endFormTag()# 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/textarea.txt: -------------------------------------------------------------------------------- 1 | 2 | #textArea(label="Overview", objectName="article", property="overview")# 3 | 4 | 5 |
6 | Screenshots 7 | 8 | #fileField(label="File #i#", objectName="site", association="screenshots", position=i, property="file")# 9 | #textArea(label="Caption ##i#", objectName="site", association="screenshots", position=i, property="caption")# 10 | 11 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/textareatag.txt: -------------------------------------------------------------------------------- 1 | 2 | #textAreaTag(label="Description", name="description", content=params.description)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/textfield.txt: -------------------------------------------------------------------------------- 1 | 2 | #textField(label="First Name", objectName="user", property="firstName")# 3 | 4 | 5 |
6 | Phone Numbers 7 | 8 | #textField(label="Phone ##i#", objectName="contact", association="phoneNumbers", position=i, property="phoneNumber")# 9 | 10 |
-------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/textfieldtag.txt: -------------------------------------------------------------------------------- 1 | 2 | #textFieldTag(label="Search", name="q", value=params.q)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/timeagoinwords.txt: -------------------------------------------------------------------------------- 1 | // Controller code. 2 | aWhileAgo = DateAdd("d", -90, Now()); 3 | 4 | // View code. 5 | 6 | #timeAgoInWords(aWhileAgo)# 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/timeselect.txt: -------------------------------------------------------------------------------- 1 | 2 | #timeSelect(objectName="business", property="openUntil")# 3 | 4 | 5 | #timeSelect(objectName="business", property="openUntil", order="hour,minute")# 6 | 7 | 8 | #timeSelect(objectName="appointment", property="dateTimeStart", minuteStep=15)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/timeselecttags.txt: -------------------------------------------------------------------------------- 1 | 2 | #timeSelectTags(name="timeOfMeeting" selected=params.timeOfMeeting)# 3 | 4 | 5 | #timeSelectTags(name="timeOfMeeting", selected=params.timeOfMeeting, order="hour,minute")# 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/timeuntilinwords.txt: -------------------------------------------------------------------------------- 1 | // Controller code. 2 | aLittleAhead = DateAdd("d", 365, Now()); 3 | 4 | // View code. 5 | 6 | #timeUntilInWords(aLittleAhead)# 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/titleize.txt: -------------------------------------------------------------------------------- 1 | 2 | #titleize("CFWheels is a framework for ColdFusion")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/truncate.txt: -------------------------------------------------------------------------------- 1 | 2 | #truncate(text="CFWheels is a framework for ColdFusion", length=20)# 3 | 4 | 5 | #truncate(text="CFWheels is a framework for ColdFusion", truncateString=" (more)")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/urlfor.txt: -------------------------------------------------------------------------------- 1 | 2 | #urlFor(controller="account", action="logOut")# 3 | 4 | 5 | #urlFor(action="comments", anchor="comment10")# 6 | 7 | 8 | #urlFor(route="product", categorySlug="accessories", productSlug="battery-charger")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/useslayout.txt: -------------------------------------------------------------------------------- 1 | // We want this layout to be used as the default throughout the 2 | // entire controller, except for the `myAjax` action. 3 | usesLayout(template="myLayout", except="myAjax"); 4 | 5 | // Use a custom layout for these actions but use the default 6 | // `layout.cfm` for the rest. 7 | usesLayout(template="myLayout", only="termsOfService,shippingPolicy"); 8 | 9 | // Define a custom function to decide which layout to display. 10 | // The `setLayout` function should return the name of the layout 11 | // to use or `true` to use the default one. 12 | usesLayout("setLayout"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/verificationchain.txt: -------------------------------------------------------------------------------- 1 | // Get verification chain, remove the first item, and set it back. 2 | myVerificationChain = verificationChain(); 3 | ArrayDeleteAt(myVerificationChain, 1); 4 | setVerificationChain(myVerificationChain); 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/verifies.txt: -------------------------------------------------------------------------------- 1 | // Tell CFWheels to verify that the `handleForm` action is always a `POST` request when executed. 2 | verifies(only="handleForm", post=true); 3 | 4 | // Make sure that the edit action is a `GET` request, that `userId` exists in the `params` struct, and that it's an integer. 5 | verifies(only="edit", get=true, params="userId", paramsTypes="integer"); 6 | 7 | // Just like above, only this time we want to invoke a custom function in our controller to handle the request when it is invalid. 8 | verifies(only="edit", get=true, params="userId", paramsTypes="integer", handler="myCustomFunction"); 9 | 10 | // Just like above, only this time instead of specifying a handler, we want to `redirect` the visitor to the index action of the controller and show an error in The Flash when the request is invalid. 11 | verifies(only="edit", get=true, params="userId", paramsTypes="integer", action="index", error="Invalid userId"); 12 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/wordtruncate.txt: -------------------------------------------------------------------------------- 1 | 2 | #wordTruncate(text="CFWheels is a framework for ColdFusion", length=4)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/controller/yearselecttag.txt: -------------------------------------------------------------------------------- 1 | 2 | #yearSelectTag(name="yearOfBirthday", selected=params.yearOfBirthday)# 3 | 4 | // Only allow selection of year to be for the past 50 years, minimum being 18 years ago 5 | fiftyYearsAgo = Now() - 50; 6 | eighteenYearsAgo = Now() - 18; 7 | 8 | 9 | #yearSelectTag(name="yearOfBirthday", selected=params.yearOfBirthday, startYear=fiftyYearsAgo, endYear=eighteenYearsAgo)# -------------------------------------------------------------------------------- /wheels/public/docs/reference/deprecated/findorcreateby[property].txt: -------------------------------------------------------------------------------- 1 | // Return the first object that matches "Timberlake" in the last name column. If there is no match, create a new one and set firstName to "Justin". 2 | newArtist = model("artist").findOrCreateByLastName(lastName="Timberlake", firstName="Justin"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/collection.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | mapper() 5 | // Create a route like `photos/search` 6 | .resources(name="photos", nested=true) 7 | .collection() 8 | .get("search") 9 | .end() 10 | .end() 11 | .end(); 12 | 13 | 14 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/delete.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | // Route name: articleReview 5 | // Example URL: /articles/987/reviews/12542 6 | // Controller: Reviews 7 | // Action: delete 8 | .delete(name="articleReview", pattern="articles/[articleKey]/reviews/[key]", to="reviews##delete") 9 | 10 | // Route name: cookedBooks 11 | // Example URL: /cooked-books 12 | // Controller: CookedBooks 13 | // Action: delete 14 | .delete(name="cookedBooks", controller="cookedBooks", action="delete") 15 | 16 | // Route name: logout 17 | // Example URL: /logout 18 | // Controller: Sessions 19 | // Action: delete 20 | .delete(name="logout", to="sessions##delete") 21 | 22 | // Route name: clientsStatus 23 | // Example URL: /statuses/4918 24 | // Controller: clients.Statuses 25 | // Action: delete 26 | .delete(name="statuses", to="statuses##delete", package="clients") 27 | 28 | // Route name: blogComment 29 | // Example URL: /comments/5432 30 | // Controller: blog.Comments 31 | // Action: delete 32 | .delete( 33 | name="comment", 34 | pattern="comments/[key]", 35 | to="comments##delete", 36 | package="blog" 37 | ) 38 | .end(); 39 | 40 | 41 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/end.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | .namespace("admin") 5 | .resources("products") 6 | .end() // Ends the `namespace` block. 7 | 8 | .scope(package="public") 9 | .resources(name="products", nested=true) 10 | .resources("variations") 11 | .end() // Ends the nested `resources` block. 12 | .end() // Ends the `scope` block. 13 | .end(); // Ends the `mapper` block. 14 | 15 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/mapper.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | .namespace("admin") 5 | .resources("users") 6 | .end() 7 | 8 | .resource("profile") 9 | 10 | .get(name="login", to="sessions##new") 11 | .post(name="auth", to="sessions##create") 12 | .delete(name="logout", to="sessions##delete") 13 | .end(); 14 | 15 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/member.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | // Create a route like `photos/1/preview` 5 | .resources(name="photos", nested=true) 6 | .member() 7 | .get("preview") 8 | .end() 9 | .end() 10 | .end(); 11 | 12 | 13 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/namespace.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | .namespace("api") 5 | .namespace("v2") 6 | // Route name: apiV2Products 7 | // Example URL: /api/v2/products/1234 8 | // Controller: api.v2.Products 9 | .resources("products") 10 | .end() 11 | 12 | .namespace("v1") 13 | // Route name: apiV1Users 14 | // Example URL: /api/v1/users 15 | // Controller: api.v1.Users 16 | .get(name="users", to="users##index") 17 | .end() 18 | .end() 19 | 20 | .namespace(name="foo", package="foos", path="foose") 21 | // Route name: fooBars 22 | // Example URL: /foose/bars 23 | // Controller: foos.Bars 24 | .post(name="bars", to="bars##create") 25 | .end() 26 | .end(); 27 | 28 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/package.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | .package("public") 5 | // Example URL: /products/1234 6 | // Controller: public.Products 7 | .resources("products") 8 | .end() 9 | 10 | // Example URL: /users/4321 11 | // Controller: Users 12 | .resources(name="users", nested=true) 13 | // Calling `package` here is useful to scope nested routes for the `users` 14 | // resource into a subfolder. 15 | .package("users") 16 | // Example URL: /users/4321/profile 17 | // Controller: users.Profiles 18 | .resource("profile") 19 | .end() 20 | .end() 21 | .end(); 22 | 23 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/resource.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | // With default arguments 5 | .resource("checkout") 6 | 7 | // Point auth URL to controller at `controllers/sessions/Auth.cfc` 8 | .resource(name="auth", controller="sessions.auth") 9 | 10 | // Limited list of routes generated by `only` argument. 11 | .resource(name="profile", only="show,edit,update") 12 | 13 | // Limited list of routes generated by `except` argument. 14 | .resource(name="cart", except="new,create,edit,delete") 15 | 16 | // Nested resource 17 | .resource(name="preferences", only="index", nested=true) 18 | .get(name="editPassword", to="passwords##edit") 19 | .patch(name="password", to="passwords##update") 20 | 21 | .resources("foods") 22 | .end() 23 | 24 | // Overridden `path` 25 | .resource(name="blogPostOptions", path="blog-post/options") 26 | .end(); 27 | 28 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/resources.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | // With default arguments 5 | .resources("admins") 6 | 7 | // Point authors URL to controller at `controllers/Users.cfc` 8 | .resources(name="authors", controller="users") 9 | 10 | // Limited list of routes generated by `only` argument. 11 | .resources(name="products", only="index,show,edit,update") 12 | 13 | // Limited list of routes generated by `except` argument. 14 | .resources(name="orders", except="delete") 15 | 16 | // Nested resources 17 | .resources(name="stories", nested=true) 18 | .resources("heroes") 19 | .resources("villains") 20 | .end() 21 | 22 | // Overridden `path` 23 | .resources(name="blogPostsOptions", path="blog-posts/options") 24 | .end(); 25 | 26 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/root.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | .namespace("api") 5 | // Map the root of the `api` folder to the `index` action of the `apis` 6 | // controller. 7 | .root(controller="apis", action="index") 8 | .end() 9 | 10 | // Map the root of the application to the `show` action of the `dashboards` 11 | // controller. 12 | .root(to="dashboards##show") 13 | .end(); 14 | 15 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/scope.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | // All routes inside will use the `freeForAll` controller. 5 | .scope(controller="freeForAll") 6 | .get(name="bananas", action="bananas") 7 | .root(action="index") 8 | .end() 9 | 10 | // All routes's controllers inside will be inside the `public` package/subfolder. 11 | .scope(package="public") 12 | .resource(name="search", only="show,create") 13 | .end() 14 | 15 | // All routes inside will be prepended with a URL path of `phones/`. 16 | .scope(path="phones") 17 | .get(name="newest", to="phones##newest") 18 | .get(name="sortOfNew", to="phones##sortOfNew") 19 | .end() 20 | .end(); 21 | 22 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/mapper/wildcard.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | mapper() 4 | // Enables `[controller]` and `[controller]/[action]`, only via `GET` requests. 5 | .wildcard() 6 | 7 | // Enables `[controller]/[action]/[key]` as well. 8 | .wildcard(mapKey=true) 9 | 10 | // Also enables patterns like `[controller].[format]` and 11 | // `[controller]/[action].[format]` 12 | .wildcard(mapFormat=true) 13 | 14 | // Allow additional methods beyond just `GET` 15 | // 16 | // Note that this can open some serious security holes unless you use `verifies` 17 | // in the controller to make sure that requests changing data can only occur 18 | // with a `POST` method. 19 | .wildcard(methods="get,post") 20 | .end(); 21 | 22 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/addcolumn.txt: -------------------------------------------------------------------------------- 1 | addColumn(table='members', columnType='string', columnName='status', limit=50); 2 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/addindex.txt: -------------------------------------------------------------------------------- 1 | addIndex(table='members', columnNames='username', unique=true); 2 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/addrecord.txt: -------------------------------------------------------------------------------- 1 | addRecord(table='people', 2 | id = 1, 3 | title = "Mr", 4 | firstname = "Bruce", 5 | lastname = "Wayne", 6 | email = "bruce@wayneenterprises.com", 7 | tel = "555-67869099", 8 | ); 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/changecolumn.txt: -------------------------------------------------------------------------------- 1 | changeColumn(table='members', columnType='string', columnName='status', limit=50); 2 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/changetable.txt: -------------------------------------------------------------------------------- 1 | t = changeTable(name='employees'); 2 | t.string(columnNames="fullName", default="", null=true, limit="255"); 3 | t.change(); 4 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/createtable.txt: -------------------------------------------------------------------------------- 1 | // Example: create a users table 2 | t = createTable(name='users'); 3 | t.string(columnNames='firstname,lastname', default='', null=false, limit=50); 4 | t.string(columnNames='email', default='', null=false, limit=255); 5 | t.string(columnNames='passwordHash', default='', null=true, limit=500); 6 | t.string(columnNames='passwordResetToken,verificationToken', default='', null=true, limit=500); 7 | t.boolean(columnNames='passwordChangeRequired,verified', default=false); 8 | t.datetime(columnNames='passwordResetTokenAt,passwordResetAt,loggedinAt', default='', null=true); 9 | t.integer(columnNames='roleid', default=0, null=false, limit=3); 10 | t.timestamps(); 11 | t.create(); 12 | 13 | // Example: Create a table with a different Primary Key 14 | t = createTable(name='tokens', id=false); 15 | t.primaryKey(name='id', null=false, type="string", limit=35 ); 16 | t.datetime(columnNames="expiresAt", null=false); 17 | t.integer(columnNames='requests', default=0, null=false); 18 | t.timestamps(); 19 | t.create(); 20 | 21 | // Example: Create a Join Table with composite primary keys 22 | t = createTable(name='userkintins', id=false); 23 | t.primaryKey(name="userid", null=false, limit=11); 24 | t.primaryKey(name='profileid', type="string", limit=11 ); 25 | t.create(); 26 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/down.txt: -------------------------------------------------------------------------------- 1 | function down() { 2 | transaction { 3 | try { 4 | // your code goes here 5 | dropTable('myTable'); 6 | } catch (any e) { 7 | local.exception = e; 8 | } 9 | 10 | if (StructKeyExists(local, "exception")) { 11 | transaction action="rollback"; 12 | throw(errorCode="1", detail=local.exception.detail, message=local.exception.message, type="any"); 13 | } else { 14 | transaction action="commit"; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/removeindex.txt: -------------------------------------------------------------------------------- 1 | removeIndex(table='members',indexName='members_username'); 2 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migration/up.txt: -------------------------------------------------------------------------------- 1 | function up() { 2 | transaction { 3 | try { 4 | // your code goes here 5 | t = createTable(name='myTable'); 6 | t.timestamps(); 7 | t.create(); 8 | } catch (any e) { 9 | local.exception = e; 10 | } 11 | 12 | if (StructKeyExists(local, "exception")) { 13 | transaction action="rollback"; 14 | throw(errorCode="1", detail=local.exception.detail, message=local.exception.message, type="any"); 15 | } else { 16 | transaction action="commit"; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migrator/createmigration.txt: -------------------------------------------------------------------------------- 1 | // Create an empty migration file 2 | result=application.wheels.migrator.createMigration("MyMigrationFile"); 3 | 4 | // Or Create a migration file from the create-table template 5 | result=application.wheels.migrator.createMigration("MyMigrationFile","create-table"); 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migrator/getavailablemigrations.txt: -------------------------------------------------------------------------------- 1 | // Get array of available migrations 2 | migrations = application.wheels.migrator.getAvailableMigrations(); 3 | 4 | if(ArrayLen(migrations)){ 5 | latestVersion = migrations[ArrayLen(migrations)].version; 6 | } else { 7 | latestVersion = 0; 8 | } 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migrator/getcurrentmigrationversion.txt: -------------------------------------------------------------------------------- 1 | // Get current database version 2 | currentVersion = application.wheels.migrator.getCurrentMigrationVersion(); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/migrator/migrateto.txt: -------------------------------------------------------------------------------- 1 | // Migrate to a specific version 2 | // Returns a message with the result 3 | result=application.wheels.migrator.migrateTo(version); 4 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/accessibleproperties.txt: -------------------------------------------------------------------------------- 1 | // Make `isActive` the only property that can be set through mass assignment operations like `updateAll()`. 2 | config() { 3 | accessibleProperties("isActive"); 4 | } 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/adderror.txt: -------------------------------------------------------------------------------- 1 | // Add an error to the `email` property. 2 | this.addError(property="email", message="Sorry, you are not allowed to use that email. Try again, please."); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/adderrortobase.txt: -------------------------------------------------------------------------------- 1 | // Add an error on the object that's not specific to a single property. 2 | this.addErrorToBase(message="Your email address must be the same as your domain name."); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/aftercreate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an object has been created. 2 | afterCreate("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/afterdelete.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an object has been deleted. 2 | afterDelete("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/afterfind.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `setTime` method after getting objects or records with one of the finder methods. 2 | config() { 3 | afterFind("setTime"); 4 | } 5 | 6 | function setTime(){ 7 | arguments.fetchedAt = Now(); 8 | return arguments; 9 | } 10 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/afterinitialization.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an object has been initialized (i.e. after creating it or fetching it with a finder method). 2 | afterInitialization("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/afternew.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after a new object has been created. 2 | afterNew("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/aftersave.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an object has been saved. 2 | afterSave("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/afterupdate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an object has been updated. 2 | afterUpdate("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/aftervalidation.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an object has been validated. 2 | afterValidation("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/aftervalidationoncreate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after a new object has been validated. 2 | afterValidationOnCreate("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/aftervalidationonupdate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method after an existing object has been validated. 2 | afterValidationOnUpdate("fixObj"); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/allchanges.txt: -------------------------------------------------------------------------------- 1 | // Get an object, change it, and then ask for its changes (will return a struct containing the changes, both property names and their values). 2 | member = model("member").findByKey(params.memberId); 3 | member.firstName = params.newFirstName; 4 | member.email = params.newEmail; 5 | allChanges = member.allChanges(); 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/allerrors.txt: -------------------------------------------------------------------------------- 1 | // Get all the errors for the `user` object. 2 | errorInfo = user.allErrors(); 3 | 4 | // Sample return of method. 5 | [ 6 | { 7 | message: 'Username must not be blank.', 8 | name: 'usernameError', 9 | property: 'username' 10 | }, 11 | { 12 | message: 'Password must not be blank.', 13 | name: 'passwordError', 14 | property: 'password' 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/automaticvalidations.txt: -------------------------------------------------------------------------------- 1 | // Disable automatic validations (for example when automatic validations are enabled globally, but we want to disable just for this model). 2 | config() { 3 | automaticValidations(false); 4 | } 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/average.txt: -------------------------------------------------------------------------------- 1 | // Get the average salary for all employees. 2 | avgSalary = model("employee").average("salary"); 3 | 4 | // Get the average salary for employees in a given department. 5 | avgSalary = model("employee").average(property="salary", where="departmentId=#params.key#"); 6 | 7 | // Make sure a numeric value is always returned if no records are calculated. 8 | avgSalary = model("employee").average(property="salary", where="salary BETWEEN #params.min# AND #params.max#", ifNull=0); 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforecreate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeCreate("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforedelete.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeDelete("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforesave.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeSave("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforeupdate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeUpdate("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforevalidation.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeValidation("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforevalidationoncreate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeValidationOnCreate("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/beforevalidationonupdate.txt: -------------------------------------------------------------------------------- 1 | // Instruct CFWheels to call the `fixObj` method 2 | beforeValidationOnUpdate("fixObj"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/belongsto.txt: -------------------------------------------------------------------------------- 1 | // Specify that instances of this model belong to an author. (The table for this model should have a foreign key set on it, typically named `authorid`.) 2 | belongsTo("author"); 3 | 4 | // Same as above, but because we have broken away from the foreign key naming convention, we need to set `modelName` and `foreignKey`. 5 | belongsTo(name="bookWriter", modelName="author", foreignKey="authorId"); 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/changedfrom.txt: -------------------------------------------------------------------------------- 1 | // Get a member object and change the `email` property on it 2 | member = model("member").findByKey(params.memberId); 3 | member.email = params.newEmail; 4 | 5 | // Get the previous value (what the `email` property was before it was changed) 6 | oldValue = member.changedFrom("email"); 7 | 8 | // The above can also be done using a dynamic function like this 9 | oldValue = member.emailChangedFrom(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/changedproperties.txt: -------------------------------------------------------------------------------- 1 | // Get an object, change it, and then ask for its changes (will return a list of the property names that have changed, not the values themselves) 2 | member = model("member").findByKey(params.memberId); 3 | member.firstName = params.newFirstName; 4 | member.email = params.newEmail; 5 | changedProperties = member.changedProperties(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/clearchangeinformation.txt: -------------------------------------------------------------------------------- 1 | // Convert startTime to UTC (maybe done in an "after find" call back) but then tell CFWheels to clear the information about this change (but not the change itself) so that it won't attempt to save the new value to the database, report it as being changed when calling hasChanged() etc. 2 | 3 | this.startTime = DateConvert("Local2UTC", this.startTime); 4 | this.clearChangeInformation(property="startTime"); 5 | 6 | // Clear information for all properties 7 | this.clearChangeInformation(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/clearerrors.txt: -------------------------------------------------------------------------------- 1 | // Clear all errors on the object as a whole 2 | this.clearErrors(); 3 | 4 | // Clear all errors on `firstName` 5 | this.clearErrors("firstName"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/count.txt: -------------------------------------------------------------------------------- 1 | // Count how many authors there are in the table 2 | authorCount = model("author").count(); 3 | 4 | // Count how many authors that have a last name starting with an "A" 5 | authorOnACount = model("author").count(where="lastName LIKE 'A%'"); 6 | 7 | // Count how many authors that have written books starting with an "A" 8 | authorWithBooksOnACount = model("author").count(include="books", where="booktitle LIKE 'A%'"); 9 | 10 | // Count the number of comments on a specific post (a `hasMany` association from `post` to `comment` is required) 11 | // The `commentCount` method will call `model("comment").count(where="postId=#post.id#")` internally 12 | aPost = model("post").findByKey(params.postId); 13 | amount = aPost.commentCount(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/create.txt: -------------------------------------------------------------------------------- 1 | // Create a new author and save it to the database 2 | newAuthor = model("author").create(params.author); 3 | 4 | // Same as above using named arguments 5 | newAuthor = model("author").create(firstName="John", lastName="Doe"); 6 | 7 | // Same as above using both named arguments and a struct 8 | newAuthor = model("author").create(active=1, properties=params.author); 9 | 10 | // If you have a `hasOne` or `hasMany` association setup from `customer` to `order`, you can do a scoped call. (The `createOrder` method below will call `model("order").create(customerId=aCustomer.id, shipping=params.shipping)` internally.) 11 | aCustomer = model("customer").findByKey(params.customerId); 12 | anOrder = aCustomer.createOrder(shipping=params.shipping); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/datasource.txt: -------------------------------------------------------------------------------- 1 | // In models/User.cfc. 2 | config() { 3 | // Tell Wheels to use the data source named `users_source` instead of the default one whenever this model makes SQL calls. 4 | dataSource("users_source"); 5 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/delete.txt: -------------------------------------------------------------------------------- 1 | // Get a post object and then delete it from the database. 2 | post = model("post").findByKey(33); 3 | post.delete(); 4 | 5 | // If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `deleteComment` method below will call `comment.delete()` internally.) 6 | post = model("post").findByKey(params.postId); 7 | comment = model("comment").findByKey(params.commentId); 8 | post.deleteComment(comment); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/deleteall.txt: -------------------------------------------------------------------------------- 1 | // Delete all inactive users without instantiating them (will skip validation and callbacks). 2 | recordsDeleted = model("user").deleteAll(where="inactive=1", instantiate=false); 3 | 4 | // If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `deleteAllComments` method below will call `model("comment").deleteAll(where="postId=#post.id#")` internally.) 5 | post = model("post").findByKey(params.postId); 6 | howManyDeleted = post.deleteAllComments(); 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/deletebykey.txt: -------------------------------------------------------------------------------- 1 | // Delete the user with the primary key value of `1`. 2 | result = model("user").deleteByKey(1); 3 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/deleteone.txt: -------------------------------------------------------------------------------- 1 | // Delete the user that signed up last. 2 | result = model("user").deleteOne(order="signupDate DESC"); 3 | 4 | // If you have a `hasOne` association setup from `user` to `profile` you can do a scoped call (the `deleteProfile` method below will call `model("profile").deleteOne(where="userId=#aUser.id#")` internally). 5 | aUser = model("user").findByKey(params.userId); 6 | aUser.deleteProfile(); 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/errorcount.txt: -------------------------------------------------------------------------------- 1 | // Check how many errors are set on the object 2 | if(author.errorCount() GTE 10){ 3 | // Do something to deal with this very erroneous author here... 4 | } 5 | 6 | // Check how many errors are associated with the `email` property 7 | if(author.errorCount("email") gt 0){ 8 | // Do something to deal with this erroneous author here... 9 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/errormessageon.txt: -------------------------------------------------------------------------------- 1 | 2 | #errorMessageOn(objectName="user", property="email")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/errormessagesfor.txt: -------------------------------------------------------------------------------- 1 | 2 | #errorMessagesFor(objectName="user")# -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/errorson.txt: -------------------------------------------------------------------------------- 1 | // Get all errors related to the email address of the user object 2 | errors = user.errorsOn("emailAddress"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/errorsonbase.txt: -------------------------------------------------------------------------------- 1 | // Get all general type errors for the user object 2 | errors = user.errorsOnBase(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/exists.txt: -------------------------------------------------------------------------------- 1 | // Checking if Joe exists in the database 2 | result = model("user").exists(where="firstName = 'Joe'"); 3 | 4 | // Checking if a specific user exists based on a primary key valued passed in through the URL/form in an if statement 5 | if (model("user").exists(keyparams.key)) 6 | { 7 | // Do something 8 | } 9 | 10 | // If you have a `belongsTo` association setup from `comment` to `post`, you can do a scoped call. (The `hasPost` method below will call `model("post").exists(comment.postId)` internally.) 11 | comment = model("comment").findByKey(params.commentId); 12 | commentHasAPost = comment.hasPost(); 13 | 14 | // If you have a `hasOne` association setup from `user` to `profile`, you can do a scoped call. (The `hasProfile` method below will call `model("profile").exists(where="userId=#user.id#")` internally.) 15 | user = model("user").findByKey(params.userId); 16 | userHasProfile = user.hasProfile(); 17 | 18 | // If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `hasComments` method below will call `model("comment").exists(where="postid=#post.id#")` internally.) 19 | post = model("post").findByKey(params.postId); 20 | postHasComments = post.hasComments(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/findallkeys.txt: -------------------------------------------------------------------------------- 1 | // basic usage 2 | primaryKeyList = model("artist").findAllKeys(); 3 | 4 | // Quote values, use a different delimiter and filter results with the "where" argument 5 | primaryKeyList = model("artist").findAllKeys(quoted=true, delimiter="-", where="active=1"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/findbykey.txt: -------------------------------------------------------------------------------- 1 | // Getting the author with the primary key value `99` as an object 2 | auth = model("author").findByKey(99); 3 | 4 | // Getting an author based on a form/URL value and then checking if it was found 5 | auth = model("author").findByKey(params.key); 6 | if(!isObject(auth)){ 7 | flashInsert(message="Author #params.key# was not found"); 8 | redirectTo(back=true); 9 | } 10 | 11 | // If you have a `belongsTo` association setup from `comment` to `post`, you can do a scoped call. (The `post` method below will call `model("post").findByKey(comment.postId)` internally) 12 | comment = model("comment").findByKey(params.commentId); 13 | post = comment.post(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/findone.txt: -------------------------------------------------------------------------------- 1 | // Getting the most recent order as an object from the database 2 | order = model("order").findOne(order="datePurchased DESC"); 3 | 4 | // Using a dynamic finder to get the first person with the last name `Smith`. Same as calling `model("user").findOne(where"lastName='Smith'")` 5 | person = model("user").findOneByLastName("Smith"); 6 | 7 | // Getting a specific user using a dynamic finder. Same as calling `model("user").findOne(where"email='someone@somewhere.com' AND password='mypass'")` 8 | user = model("user").findOneByEmailAndPassword("someone@somewhere.com,mypass"); 9 | 10 | // If you have a `hasOne` association setup from `user` to `profile`, you can do a scoped call. (The `profile` method below will call `model("profile").findOne(where="userId=#user.id#")` internally) 11 | user = model("user").findByKey(params.userId); 12 | profile = user.profile(); 13 | 14 | // If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `findOneComment` method below will call `model("comment").findOne(where="postId=#post.id#")` internally) 15 | post = model("post").findByKey(params.postId); 16 | comment = post.findOneComment(where="text='I Love Wheels!'"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/gettablenameprefix.txt: -------------------------------------------------------------------------------- 1 | // Get the table name prefix for this user when running a custom query. 2 | 3 | 4 | SELECT * 5 | FROM #this.getTableNamePrefix()#users 6 | WHERE disabled = 1 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/haschanged.txt: -------------------------------------------------------------------------------- 1 | // Get a member object and change the `email` property on it 2 | member = model("member").findByKey(params.memberId); 3 | member.email = params.newEmail; 4 | 5 | // Check if the `email` property has changed 6 | if(member.hasChanged("email")){ 7 | // Do something... 8 | } 9 | 10 | // The above can also be done using a dynamic function like this 11 | if(member.emailHasChanged()){ 12 | // Do something... 13 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/haserrors.txt: -------------------------------------------------------------------------------- 1 | // Check if the post object has any errors set on it 2 | if(post.hasErrors()){ 3 | // Send user to a form to correct the errors... 4 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/hasmany.txt: -------------------------------------------------------------------------------- 1 | // Specify that instances of this model has many comments (the table for the associated model, not the current, should have the foreign key set on it). 2 | hasMany("comments"); 3 | 4 | // Specify that this model (let's call it `reader` in this case) has many subscriptions and setup a shortcut to the `publication` model (useful when dealing with many-to-many relationships). 5 | hasMany(name="subscriptions", shortcut="publications"); 6 | 7 | // Automatically delete all associated `comments` whenever this object is deleted. 8 | hasMany(name="comments", dependent="deleteAll"); 9 | 10 | // When not following CFWheels naming conventions for associations, it can get complex to define how a `shortcut` works. 11 | // In this example, we are naming our `shortcut` differently than the actual model's name. 12 | 13 | // In the models/Customer.cfc `config()` method. 14 | hasMany(name="subscriptions", shortcut="magazines", through="publication,subscriptions"); 15 | 16 | // In the models/Subscription.cfc `config()` method. 17 | belongsTo("customer"); 18 | belongsTo("publication"); 19 | 20 | // In the models/Publication `config()` method. 21 | hasMany("subscriptions"); 22 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/hasone.txt: -------------------------------------------------------------------------------- 1 | // Specify that instances of this model has one profile. (The table for the associated model, not the current, should have the foreign key set on it.) 2 | hasOne("profile"); 3 | 4 | // Same as above but setting the `joinType` to `inner`, which basically means this model should always have a record in the `profiles` table. 5 | hasOne(name="profile", joinType="inner"); 6 | 7 | // Automatically delete the associated `profile` whenever this object is deleted. 8 | hasMany(name="comments", dependent="delete"); 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/hasproperty.txt: -------------------------------------------------------------------------------- 1 | // Get an object, set a value and then see if the property exists 2 | employee = model("employee").new(); 3 | employee.firstName = "dude"; 4 | employee.hasProperty("firstName"); // returns true 5 | 6 | // This is also a dynamic method that you could do 7 | employee.hasFirstName(); 8 | 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/invokewithtransaction.txt: -------------------------------------------------------------------------------- 1 | // This is the method to be run inside a transaction. 2 | public boolean function transferFunds(required any personFrom, required any personTo, required numeric amount) { 3 | if (arguments.personFrom.withdraw(arguments.amount) && arguments.personTo.deposit(arguments.amount)) { 4 | return true; 5 | } else { 6 | return false; 7 | } 8 | } 9 | 10 | local.david = model("Person").findOneByName("David"); 11 | local.mary = model("Person").findOneByName("Mary"); 12 | invokeWithTransaction(method="transferFunds", personFrom=local.david, personTo=local.mary, amount=100); 13 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/isclass.txt: -------------------------------------------------------------------------------- 1 | // Use the passed in `id` when we're already in an instance 2 | function memberIsAdmin(){ 3 | if(isClass()){ 4 | return this.findByKey(arguments.id).admin; 5 | } else { 6 | return this.admin; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/isinstance.txt: -------------------------------------------------------------------------------- 1 | // Use the passed in `id` when we're not already in an instance 2 | function memberIsAdmin(){ 3 | if(isInstance()){ 4 | return this.admin; 5 | } else { 6 | return this.findByKey(arguments.id).admin; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/isnew.txt: -------------------------------------------------------------------------------- 1 | // Create a new object and then check if it is new (yes, this example is ridiculous. It makes more sense in the context of callbacks for example) 2 | employee = model("employee").new()> 3 | 4 | // Do something... 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/key.txt: -------------------------------------------------------------------------------- 1 | // Get an object and then get the primary key value(s) 2 | employee = model("employee").findByKey(params.key); 3 | val = employee.key(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/maximum.txt: -------------------------------------------------------------------------------- 1 | // Get the amount of the highest salary for all employees 2 | highestSalary = model("employee").maximum("salary"); 3 | 4 | // Get the amount of the highest salary for employees in a given department 5 | highestSalary = model("employee").maximum(property="salary", where="departmentId=#params.key#"); 6 | 7 | // Make sure a numeric value is always returned, even if no records are found to calculate the maximum for 8 | highestSalary = model("employee").maximum(property="salary", where="salary > #params.minSalary#", ifNull=0); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/minimum.txt: -------------------------------------------------------------------------------- 1 | // Get the amount of the lowest salary for all employees 2 | lowestSalary = model("employee").minimum("salary"); 3 | 4 | // Get the amount of the lowest salary for employees in a given department 5 | lowestSalary = model("employee").minimum(property="salary", where="departmentId=#params.key#"); 6 | 7 | // Make sure a numeric amount is always returned, even when there were no records analyzed by the query 8 | lowestSalary = model("employee").minimum(property="salary", where="salary BETWEEN #params.min# AND #params.max#", ifNull=0); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/nestedproperties.txt: -------------------------------------------------------------------------------- 1 | // In `models/User.cfc`, allow for `groupEntitlements` to be saved and deleted through the `user` object. 2 | function config(){ 3 | hasMany("groupEntitlements"); 4 | nestedProperties(association="groupEntitlements", allowDelete=true); 5 | } 6 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/new.txt: -------------------------------------------------------------------------------- 1 | // Create a new author in memory (not saved to the database) 2 | newAuthor = model("author").new(); 3 | 4 | // Create a new author based on properties in a struct 5 | newAuthor = model("author").new(params.authorStruct); 6 | 7 | // Create a new author by passing in named arguments 8 | newAuthor = model("author").new(firstName="John", lastName="Doe"); 9 | 10 | // If you have a `hasOne` or `hasMany` association setup from `customer` to `order`, you can do a scoped call. (The `newOrder` method below will call `model("order").new(customerId=aCustomer.id)` internally.) 11 | aCustomer = model("customer").findByKey(params.customerId); 12 | anOrder = aCustomer.newOrder(shipping=params.shipping); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/primarykey.txt: -------------------------------------------------------------------------------- 1 | // Get the name of the primary key of the table mapped to the `employee` model (which is the `employees` table by default) 2 | keyName = model("employee").primaryKey(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/primarykeys.txt: -------------------------------------------------------------------------------- 1 | // Get a list of the names of the primary keys in the table mapped to the `employee` model (which is the `employees` table by default) 2 | keyNames = model("employee").primaryKeys(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/properties.txt: -------------------------------------------------------------------------------- 1 | // Get a structure of all the properties for an object 2 | user = model("user").findByKey(1); 3 | props = user.properties(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/property.txt: -------------------------------------------------------------------------------- 1 | // Tell Wheels that when we are referring to `firstName` in the CFML code, it should translate to the `STR_USERS_FNAME` column when interacting with the database instead of the default (which would be the `firstname` column) 2 | property(name="firstName", column="STR_USERS_FNAME"); 3 | 4 | // Tell Wheels that when we are referring to `fullName` in the CFML code, it should concatenate the `STR_USERS_FNAME` and `STR_USERS_LNAME` columns 5 | property(name="fullName", sql="STR_USERS_FNAME + ' ' + STR_USERS_LNAME"); 6 | 7 | // Tell Wheels that when displaying error messages or labels for form fields, we want to use `First name(s)` as the label for the `STR_USERS_FNAME` column 8 | property(name="firstName", label="First name(s)"); 9 | 10 | // Tell Wheels that when creating new objects, we want them to be auto-populated with a `firstName` property of value `Dave` 11 | property(name="firstName", defaultValue="Dave"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/propertyispresent.txt: -------------------------------------------------------------------------------- 1 | // Get an object, set a value and then see if the property exists 2 | employee = model("employee").new(); 3 | employee.firstName = "dude"; 4 | return employee.propertyIsPresent("firstName"); // Returns true 5 | 6 | employee.firstName = ""> 7 | return employee.propertyIsPresent("firstName"); // Returns false -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/propertynames.txt: -------------------------------------------------------------------------------- 1 | // Get a list of the property names in use in the user model 2 | propNames = model("user").propertyNames(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/protectedproperties.txt: -------------------------------------------------------------------------------- 1 | // In `models/User.cfc`, `firstName` and `lastName` cannot be changed through mass assignment operations like `updateAll()`. 2 | function config(){ 3 | protectedProperties("firstName,lastName"); 4 | } 5 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/reload.txt: -------------------------------------------------------------------------------- 1 | // Get an object, call a method on it that could potentially change values, and then reload the values from the database 2 | employee = model("employee").findByKey(params.key); 3 | employee.someCallThatChangesValuesInTheDatabase(); 4 | employee.reload(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/save.txt: -------------------------------------------------------------------------------- 1 | // Save the user object to the database (will automatically do an `INSERT` or `UPDATE` statement depending on if the record is new or already exists 2 | user.save(); 3 | 4 | // Save the user object directly in an if statement without using `cfqueryparam` and take appropriate action based on the result 5 | if(user.save(parameterize=false)){ 6 | flashInsert(notice="The user was saved!"); 7 | redirectTo(action="edit"); 8 | } else { 9 | flashInsert(alert="Error, please correct!"); 10 | renderView(action="edit"); 11 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/setprimarykey.txt: -------------------------------------------------------------------------------- 1 | // In `models/User.cfc`, define the primary key as a column called `userID`. 2 | function config(){ 3 | setPrimaryKey("userID"); 4 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/setprimarykeys.txt: -------------------------------------------------------------------------------- 1 | // In `models/Subscription.cfc`, define the primary key as composite of the columns `customerId` and `publicationId`. 2 | function config(){ 3 | setPrimaryKeys("customerId,publicationId"); 4 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/setproperties.txt: -------------------------------------------------------------------------------- 1 | // Update the properties of the object with the params struct containing the values of a form post 2 | user = model("user").findByKey(1); 3 | user.setProperties(params.user); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/settablenameprefix.txt: -------------------------------------------------------------------------------- 1 | // In `models/User.cfc`, add a prefix to the default table name of `tbl`. 2 | function config(){ 3 | setTableNamePrefix("tbl"); 4 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/sum.txt: -------------------------------------------------------------------------------- 1 | // Get the sum of all salaries 2 | allSalaries = model("employee").sum("salary"); 3 | 4 | // Get the sum of all salaries for employees in a given country 5 | allAustralianSalaries = model("employee").sum(property="salary", include="country", where="countryname='Australia'"); 6 | 7 | // Make sure a numeric value is always returned, even if there are no records analyzed by the query 8 | salarySum = model("employee").sum(property="salary", where="salary BETWEEN #params.min# AND #params.max#", ifNull=0); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/table.txt: -------------------------------------------------------------------------------- 1 | // In models/User.cfc. 2 | function config() { 3 | // Tell Wheels to use the `tbl_USERS` table in the database for the `user` model instead of the default (which would be `users`). 4 | table("tbl_USERS"); 5 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/tablename.txt: -------------------------------------------------------------------------------- 1 | // Check what table the user model uses 2 | whatAmIMappedTo = model("user").tableName(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/toggle.txt: -------------------------------------------------------------------------------- 1 | // Get an object, and toggle a boolean property 2 | user = model("user").findByKey(58); 3 | isSuccess = user.toggle("isActive"); // returns whether the object was saved properly 4 | 5 | // You can also use a dynamic helper for this 6 | isSuccess = user.toggleIsActive(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/update.txt: -------------------------------------------------------------------------------- 1 | // Get a post object and then update its title in the database 2 | post = model("post").findByKey(33); 3 | post.update(title="New version of Wheels just released"); 4 | 5 | // Get a post object and then update its title and other properties based on what is pased in from the URL/form 6 | post = model("post").findByKey(params.key); 7 | post.update(title="New version of Wheels just released", properties=params.post); 8 | 9 | // If you have a `hasOne` association setup from `author` to `bio`, you can do a scoped call. (The `setBio` method below will call `bio.update(authorId=anAuthor.id)` internally.) 10 | author = model("author").findByKey(params.authorId); 11 | bio = model("bio").findByKey(params.bioId); 12 | author.setBio(bio); 13 | 14 | // If you have a `hasMany` association setup from `owner` to `car`, you can do a scoped call. (The `addCar` method below will call `car.update(ownerId=anOwner.id)` internally.) 15 | anOwner = model("owner").findByKey(params.ownerId); 16 | aCar = model("car").findByKey(params.carId); 17 | anOwner.addCar(aCar); 18 | 19 | // If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `removeComment` method below will call `comment.update(postId="")` internally.) 20 | aPost = model("post").findByKey(params.postId); 21 | aComment = model("comment").findByKey(params.commentId); 22 | aPost.removeComment(aComment); // Get an object, and toggle a boolean property 23 | user = model("user").findByKey(58); 24 | isSuccess = user.toggle("isActive"); // returns whether the object was saved properly 25 | 26 | // You can also use a dynamic helper for this 27 | isSuccess = user.toggleIsActive(); 28 | 29 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/updateall.txt: -------------------------------------------------------------------------------- 1 | // Update the `published` and `publishedAt` properties for all records that have `published=0` 2 | recordsUpdated = model("post").updateAll( published=1, publishedAt=Now(), where="published=0" ); 3 | 4 | // If you have a `hasMany` association setup from `post` to `comment`, you can do a scoped call. (The `removeAllComments` method below will call `model("comment").updateAll(postid="", where="postId=#post.id#")` internally.) 5 | post = model("post").findByKey(params.postId); 6 | post.removeAllComments(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/updatebykey.txt: -------------------------------------------------------------------------------- 1 | // Updates the object with `33` as the primary key value with values passed in through the URL/form 2 | result = model("post").updateByKey(33, params.post); 3 | 4 | // Updates the object with `33` as the primary key using named arguments 5 | result = model("post").updateByKey(key=33, title="New version of Wheels just released", published=1); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/updateone.txt: -------------------------------------------------------------------------------- 1 | // Sets the `new` property to `1` on the most recently released product 2 | result = model("product").updateOne(order="releaseDate DESC", new=1); 3 | 4 | // If you have a `hasOne` association setup from `user` to `profile`, you can do a scoped call. (The `removeProfile` method below will call `model("profile").updateOne(where="userId=#aUser.id#", userId="")` internally.) 5 | aUser = model("user").findByKey(params.userId); 6 | aUser.removeProfile(); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/updateproperty.txt: -------------------------------------------------------------------------------- 1 | // Sets the `new` property to `1` through updateProperty() 2 | product = model("product").findByKey(56); 3 | product.updateProperty("new", 1); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/valid.txt: -------------------------------------------------------------------------------- 1 | // Check if a user is valid before proceeding with execution 2 | user = model("user").new(params.user); 3 | 4 | if user.valid(){ 5 | // Do something here 6 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validate.txt: -------------------------------------------------------------------------------- 1 | function config() { 2 | // Register the `checkPhoneNumber` method below to be called to validate objects before they are saved. 3 | validate("checkPhoneNumber"); 4 | } 5 | 6 | function checkPhoneNumber() { 7 | // Make sure area code is `614`. 8 | return Left(this.phoneNumber, 3) == "614"; 9 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validateoncreate.txt: -------------------------------------------------------------------------------- 1 | function config(){ 2 | // Register the `checkPhoneNumber` method below to be called to validate new objects before they are inserted. 3 | validateOnCreate("checkPhoneNumber"); 4 | } 5 | 6 | function checkPhoneNumber(){ 7 | // Make sure area code is `614`. 8 | return Left(this.phoneNumber, 3) == "614"; 9 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validateonupdate.txt: -------------------------------------------------------------------------------- 1 | function config(){ 2 | // Register the `check` method below to be called to validate existing objects before they are updated. 3 | validateOnUpdate("checkPhoneNumber"); 4 | } 5 | 6 | function checkPhoneNumber(){ 7 | // Make sure area code is `614` 8 | return Left(this.phoneNumber, 3) == "614"; 9 | } -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatesconfirmationof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that the user has to confirm their password correctly the first time they register (usually done by typing it again in a second form field) 2 | validatesConfirmationOf(property="password", when="onCreate", message="Your password and its confirmation do not match. Please try again."); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatesexclusionof.txt: -------------------------------------------------------------------------------- 1 | // Do not allow "PHP" or "Fortran" to be saved to the database as a cool language 2 | validatesExclusionOf(property="coolLanguage", list="php,fortran", message="Haha, you can not be serious. Try again, please."); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatesformatof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that the user has entered a correct credit card validatesFormatOf(property="cc", type="creditcard"); /* * Make sure that the user has entered an email address ending with the * `.se` domain when the `ipCheck()` method returns `true`, and it's not * Sunday. Also supply a custom error message that overrides the CFWheels * default one */ validatesFormatOf( property="email", regEx="^.*@.*\.se$", condition="ipCheck()", unless="DayOfWeek() eq 1" message="Sorry, you must have a Swedish email address to use this website." ); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatesinclusionof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that the user selects either "CFWheels" or "Rails" as their framework 2 | validatesInclusionOf(property="frameworkOfChoice", list="cfwheels,rails", message="Please try again, and this time, select a decent framework!" ); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validateslengthof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that the `firstname` and `lastName` properties are not more than 2 | // 50 characters and use square brackets to dynamically insert the property 3 | // name when the error message is displayed to the user. (The `firstName` 4 | // property will be displayed as "first name".) 5 | validatesLengthOf( 6 | properties="firstName,lastName", 7 | maximum=50, 8 | message="Please shorten your [property] please (50 characters max)." 9 | ); 10 | 11 | // Make sure that the `password` property is between 4 and 15 characters 12 | validatesLengthOf( 13 | property="password", 14 | within="4,20", 15 | message="The password length must be between 4 and 20 characters." 16 | ); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatesnumericalityof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that the score is a number with no decimals but only when a score is supplied. (Tetting `allowBlank` to `true` means that objects are allowed to be saved without scores, typically resulting in `NULL` values being inserted in the database table) 2 | validatesNumericalityOf(property="score", onlyInteger=true, allowBlank=true, message="Please enter a correct score."); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatespresenceof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that the user data can not be saved to the database without the `emailAddress` property. (It must exist and not be an empty string) 2 | validatesPresenceOf("emailAddress"); -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validatesuniquenessof.txt: -------------------------------------------------------------------------------- 1 | // Make sure that two users with the same username won't ever exist in the database table 2 | validatesUniquenessOf(property="username", message="Sorry, that username is already taken."); 3 | 4 | // Same as above but allow identical usernames as long as they belong to a different account 5 | validatesUniquenessOf(property="username", scope="accountId"); 6 | 7 | -------------------------------------------------------------------------------- /wheels/public/docs/reference/model/validationtypeforproperty.txt: -------------------------------------------------------------------------------- 1 | // first name is a varchar(50) column 2 | employee = model("employee").new(); 3 | 4 | 5 | #employee.validationTypeForProperty("firstName")# 6 | -------------------------------------------------------------------------------- /wheels/public/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "initialization.cfm"; 3 | 4 | -------------------------------------------------------------------------------- /wheels/public/initialization.cfm: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Internal function. 4 | */ 5 | public struct function $init() { 6 | return this; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /wheels/public/layout/_footer_simple.cfm: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 | 7 | 8 | -------------------------------------------------------------------------------- /wheels/public/migrator/_navigation.cfm: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /wheels/public/migrator/templating.cfm: -------------------------------------------------------------------------------- 1 | 2 | param name="request.wheels.params.migrationName"; 3 | param name="request.wheels.params.templateName"; 4 | 5 | migrator = application.wheels.migrator; 6 | 7 | if (StructKeyExists(request.wheels.params, "migrationPrefix") && Len(request.wheels.params.migrationPrefix)) { 8 | message = migrator.createMigration( 9 | request.wheels.params.migrationName, 10 | request.wheels.params.templateName, 11 | request.wheels.params.migrationPrefix 12 | ); 13 | } else { 14 | message = migrator.createMigration(request.wheels.params.migrationName, request.wheels.params.templateName); 15 | } 16 | 17 | 18 |
19 |
Result
20 | #message# 21 |
22 |
23 | -------------------------------------------------------------------------------- /wheels/public/routes.cfm: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Internal GUI Routes 4 | * TODO: formalise how the cli interacts 5 | **/ 6 | mapper() 7 | .namespace(name = "wheels") 8 | .get(name = "info", pattern = "info", to = "public##info") 9 | .get(name = "routes", pattern = "routes", to = "public##routes") 10 | .post(name = "routeTester", to = "public##routetester") 11 | .get(name = "packages", pattern = "packages/[type]", to = "public##packages") 12 | .get(name = "migratorTemplates", pattern = "migrator/templates", to = "public##migratortemplates") 13 | .post(name = "migratorTemplatesCreate", pattern = "migrator/templates", to = "public##migratortemplatescreate") 14 | .get(name = "migratorSQL", pattern = "migrator/sql/[version]", to = "public##migratorsql") 15 | .post(name = "migratorCommand", pattern = "migrator/[command]/[version]", to = "public##migratorcommand") 16 | .get(name = "migrator", pattern = "migrator", to = "public##migrator") 17 | .get(name = "tests", pattern = "tests/[type]", to = "public##tests") 18 | .get(name = "docs", pattern = "docs", to = "public##docs") 19 | .get(name = "cli", pattern = "cli", to = "public##cli") 20 | .get(name = "pluginEntry", pattern = "plugins/[name]", to = "public##pluginentry") 21 | .post(name = "pluginPost", pattern = "plugins/[name]", to = "public##pluginentry") 22 | .get(name = "plugins", pattern = "plugins", to = "public##plugins") 23 | .get(name = "build", pattern = "build", to = "public##build") 24 | .get(name = "legacy", pattern = "wheels/[view]", to = "public##legacy") 25 | .root(method = "get", to = "public##index", mapFormat = false) 26 | .end() 27 | .end(); 28 | 29 | -------------------------------------------------------------------------------- /wheels/public/tests/json.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | #SerializeJSON(testResults)# 14 | -------------------------------------------------------------------------------- /wheels/public/tests/junit.cfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | #XmlFormat(HtmlCompressFormat(testResults.results[local.i].message))##Chr(13)# 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /wheels/public/views/docs.cfm: -------------------------------------------------------------------------------- 1 | 2 | request.isFluid = true; 3 | param name="request.wheels.params.type" default="core"; 4 | param name="request.wheels.params.format" default="html"; 5 | 6 | // Example Expected comment 7 | /** 8 | * I am the function hint. Backticks replaced with code; tags below get replaced. 9 | * Tags must appear before Params 10 | * 11 | * [section: Doc Section] 12 | * [category: Doc Category] (optional, but recommended) 13 | * 14 | * @paramName Hint for Param. Backticks replaced with code; [doc: AFunctionName] replaced with link 15 | */ 16 | if (request.wheels.params.format EQ "html") { 17 | include "../layout/_header.cfm"; 18 | include "../docs/#request.wheels.params.type#.cfm"; 19 | include "../layout/_footer.cfm"; 20 | } else { 21 | include "../docs/#request.wheels.params.type#.cfm"; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /wheels/public/views/pluginentry.cfm: -------------------------------------------------------------------------------- 1 | 2 | param name="request.wheels.params.name"; 3 | 4 | if (!application.wheels.enablePluginsComponent) 5 | Throw(type = "wheels.plugins", message = "The Wheels Plugin component is disabled..."); 6 | 7 | meta = $get("pluginMeta")[request.wheels.params.name]; 8 | 9 | 10 | 11 |
12 | #pageHeader("Plugins", "What you've got loaded..")# 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | www 26 | 27 | 28 | 29 | 30 |
31 | 32 |
33 |
34 |
35 | 36 | -------------------------------------------------------------------------------- /wheels/public/views/tests.cfm: -------------------------------------------------------------------------------- 1 | 2 | setting requestTimeout=10000 showDebugOutput=false; 3 | param name="request.wheels.params.type" default="app"; 4 | param name="request.wheels.params.format" default="html"; 5 | param name="request.wheels.params.sort" default="directory"; 6 | // Run the tests. 7 | testResults = $createObjectFromRoot( 8 | fileName = "Test", 9 | method = "$WheelsRunner", 10 | options = request.wheels.params, 11 | path = application.wheels.wheelsComponentPath 12 | ); 13 | // Output the results in the requested format. 14 | include "../tests/#request.wheels.params.format#.cfm"; 15 | 16 | -------------------------------------------------------------------------------- /wheels/view/csrf.cfm: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Include this in your layouts' `head` sections to include meta tags containing the authenticity token for use by JavaScript AJAX requests needing to `POST` data to your application. 4 | * 5 | * [section: View Helpers] 6 | * [category: Miscellaneous Functions] 7 | * 8 | * @encode [see:styleSheetLinkTag]. 9 | */ 10 | string function csrfMetaTags(boolean encode) { 11 | $args(name = "csrfMetaTags", args = arguments); 12 | local.metaTags = $tag(name = "meta", attributes = {name = "csrf-param", content = "authenticityToken"}); 13 | local.metaTags &= $tag( 14 | name = "meta", 15 | attributes = {name = "csrf-token", content = $generateAuthenticityToken()}, 16 | encode = arguments.encode 17 | ); 18 | 19 | return local.metaTags; 20 | } 21 | 22 | /** 23 | * Returns a hidden form field containing a new authenticity token. 24 | * 25 | * [section: View Helpers] 26 | * [category: General Form Functions] 27 | */ 28 | string function authenticityTokenField() { 29 | // Store a new authenticity token. 30 | local.authenticityToken = $generateAuthenticityToken(); 31 | 32 | // Create hidden field containing the authenticity token. 33 | local.rv = hiddenFieldTag(name = "authenticityToken", value = local.authenticityToken); 34 | 35 | // Delete the id="authenticityToken" part of the string. 36 | // There could be multiple forms on a page and duplicate "id" attributes are not allowed in HTML. 37 | local.rv = Replace(local.rv, ' id="authenticityToken" ', " "); 38 | 39 | return local.rv; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /wheels/view/functions.cfm: -------------------------------------------------------------------------------- 1 | 2 | include "assets.cfm"; 3 | include "csrf.cfm"; 4 | include "errors.cfm"; 5 | include "forms.cfm"; 6 | include "formsassociation.cfm"; 7 | include "formsdate.cfm"; 8 | include "formsdateobject.cfm"; 9 | include "formsdateplain.cfm"; 10 | include "formsobject.cfm"; 11 | include "formsplain.cfm"; 12 | include "links.cfm"; 13 | include "miscellaneous.cfm"; 14 | include "sanitize.cfm"; 15 | 16 | -------------------------------------------------------------------------------- /wheels/view/sanitize.cfm: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Removes all links from an HTML string, leaving just the link text. 4 | * 5 | * [section: View Helpers] 6 | * [category: Sanitization Functions] 7 | * 8 | * @html The HTML to remove links from. 9 | * @encode [see:styleSheetLinkTag]. 10 | */ 11 | public string function stripLinks(required string html, boolean encode) { 12 | $args(name = "stripLinks", args = arguments); 13 | local.rv = ReReplaceNoCase( 14 | arguments.html, 15 | "(.*?)", 16 | "\1", 17 | "all" 18 | ); 19 | if (arguments.encode && $get("encodeHtmlTags")) { 20 | local.rv = EncodeForHTML($canonicalize(local.rv)); 21 | } 22 | return local.rv; 23 | } 24 | 25 | /** 26 | * Removes all HTML tags from a string. 27 | * 28 | * [section: View Helpers] 29 | * [category: Sanitization Functions] 30 | * 31 | * @html The HTML to remove tag markup from. 32 | * @encode [see:styleSheetLinkTag]. 33 | */ 34 | public string function stripTags(required string html, boolean encode) { 35 | $args(name = "stripTags", args = arguments); 36 | local.rv = ReReplaceNoCase( 37 | arguments.html, 38 | "<\ *[a-z].*?>", 39 | "", 40 | "all" 41 | ); 42 | local.rv = ReReplaceNoCase( 43 | local.rv, 44 | "<\ */\ *[a-z].*?>", 45 | "", 46 | "all" 47 | ); 48 | if (arguments.encode && $get("encodeHtmlTags")) { 49 | local.rv = EncodeForHTML($canonicalize(local.rv)); 50 | } 51 | return local.rv; 52 | } 53 | 54 | --------------------------------------------------------------------------------