Overview

Packages

  • Actions
  • Codegen
  • Controls
    • Base
  • DatabaseAdapters
  • Events
  • None
  • Sessions
  • Tests

Classes

  • AbstractControl_CodeGenerator
  • AjaxTimingForm
  • BasicForm
  • BasicOrmTests
  • BBCodeParser
  • CacheTests
  • CalculatorForm
  • CalculatorWidget
  • ComplexColumn
  • DataRepeaterExample
  • Event
  • ExampleCheckColumn1
  • ExampleCheckColumn2
  • ExampleForm
  • Examples
  • ExampleService
  • ExamplesForm
  • ExampleSingleForm
  • ExpandAsArrayTests
  • HtmlJqDoc
  • InjectForm
  • JavaScriptHelper
  • JqAttributes
  • JqControlGen
  • JqDoc
  • JqIcon
  • Method
  • ModelConnectorTests
  • MyControl
  • MyQSlider_ChangeEvent
  • NavPanel
  • NestedTabForm
  • Option
  • Order
  • PaginatorForm
  • ParamsForm
  • PersistentExampleForm
  • PersonEditPanel
  • PluginEditForm
  • PluginManagerForm
  • Project
  • ProjectEditPanel
  • ProjectListForm
  • ProjectPickerListBox
  • ProjectViewPanel
  • QAbstractCacheProvider
  • QAbstractHtmlTableColumn
  • QAbstractHtmlTableDataColumn
  • QAccordion
  • QAccordion_ActivateEvent
  • QAccordion_BeforeActivateEvent
  • QAccordion_CreateEvent
  • QAccordionBase
  • QAccordionGen
  • QAction
  • QActionControl
  • QAjaxAction
  • QAjaxControlAction
  • QAjaxResponse
  • QAlertAction
  • QApplication
  • QApplicationBase
  • QArchive
  • QAutocomplete
  • QAutocomplete_ChangeEvent
  • QAutocomplete_CloseEvent
  • QAutocomplete_CodeGenerator
  • QAutocomplete_CreateEvent
  • QAutocomplete_FocusEvent
  • QAutocomplete_OpenEvent
  • QAutocomplete_ResponseEvent
  • QAutocomplete_SearchEvent
  • QAutocomplete_SelectEvent
  • QAutocomplete_SourceEvent
  • QAutocompleteBase
  • QAutocompleteBase_CodeGenerator
  • QAutocompleteGen
  • QAutocompleteListItem
  • QBackspaceKeyEvent
  • QBaseClass
  • QBlockControl
  • QBlurControlAction
  • QBlurEvent
  • QBorderCollapse
  • QBorderStyle
  • QBrowserType
  • QButton
  • QButtonBase
  • QCache
  • QCacheDeleteAction
  • QCacheDeleteAllAction
  • QCacheProviderAPC
  • QCacheProviderLocalMemory
  • QCacheProviderLocalMemoryTest
  • QCacheProviderMemcache
  • QCacheProviderNoCache
  • QCacheProviderProxy
  • QCacheSetAction
  • QCalendar
  • QCalendarType
  • QCallType
  • QCausesValidation
  • QCellClickEvent
  • QChangeEvent
  • QCheckBox
  • QCheckBox_CodeGenerator
  • QCheckBoxBase_CodeGenerator
  • QCheckBoxLegacyColumn
  • QCheckBoxList
  • QCheckBoxList_CodeGenerator
  • QCheckBoxListBase_CodeGenerator
  • QClickEvent
  • QCodeGen
  • QCodeGenBase
  • QConfirmAction
  • QContextMenuEvent
  • QControl
  • QControl_CodeGenerator
  • QControlBase
  • QControlBase_CodeGenerator
  • QControlBaseTests
  • QControlCategoryType
  • QControlGrouping
  • QControlLabel
  • QControlProxy
  • QConvertNotation
  • QConvertNotationBase
  • QCrossScripting
  • QCryptography
  • QCss
  • QCssAction
  • QCssClassAction
  • QCssTests
  • QCsvTextBox
  • QCursor
  • QDatabaseBase
  • QDatabaseCodeGen
  • QDatabaseFieldBase
  • QDatabaseFieldType
  • QDatabaseForeignKey
  • QDatabaseIndex
  • QDatabaseResultBase
  • QDatabaseRowBase
  • QDatabaseTests
  • QDataGrid
  • QDataGrid_CheckBoxColumn
  • QDataGrid_CodeGenerator
  • QDataGrid_SortEvent
  • QDataGridBase
  • QDataGridBase_CodeGenerator
  • QDataGridLegacy
  • QDataGridLegacyBase
  • QDataGridLegacyColumn
  • QDataGridLegacyRow
  • QDataGridLegacyRowStyle
  • QDataRepeater
  • QDatepicker
  • QDatepicker_BeforeShowDayEvent
  • QDatepicker_BeforeShowEvent
  • QDatepicker_CalculateWeekEvent
  • QDatepicker_ChangeMonthYearEvent
  • QDatepicker_CloseEvent
  • QDatepicker_SelectEvent
  • QDatepicker_SelectEvent2
  • QDatepickerBase
  • QDatepickerBox
  • QDatepickerBox_BeforeShowDayEvent
  • QDatepickerBox_BeforeShowEvent
  • QDatepickerBox_CalculateWeekEvent
  • QDatepickerBox_ChangeMonthYearEvent
  • QDatepickerBox_CloseEvent
  • QDatepickerBox_CodeGenerator
  • QDatepickerBox_SelectEvent
  • QDatepickerBoxBase
  • QDatepickerBoxBase_CodeGenerator
  • QDatepickerBoxGen
  • QDatepickerGen
  • QDateTime
  • QDateTimePicker
  • QDateTimePicker_CodeGenerator
  • QDateTimePickerBase_CodeGenerator
  • QDateTimePickerFormat
  • QDateTimePickerType
  • QDateTimeSpan
  • QDateTimeTests
  • QDateTimeTextBox
  • QDbBackedFormStateHandler
  • QDbBackedSessionHandler
  • QDialog
  • QDialog_BeforeCloseEvent
  • QDialog_ButtonEvent
  • QDialog_CloseEvent
  • QDialog_CreateEvent
  • QDialog_DragEvent
  • QDialog_DragStartEvent
  • QDialog_DragStopEvent
  • QDialog_FocusEvent
  • QDialog_OpenEvent
  • QDialog_ResizeEvent
  • QDialog_ResizeStartEvent
  • QDialog_ResizeStopEvent
  • QDialogBase
  • QDialogBox
  • QDialogGen
  • QDisplayStyle
  • QDoubleClickEvent
  • QDownArrowKeyEvent
  • QDragDropEvent
  • QDraggable
  • QDraggable_CreateEvent
  • QDraggable_DragEvent
  • QDraggable_StartEvent
  • QDraggable_StopEvent
  • QDraggableBase
  • QDraggableGen
  • QDroppable
  • QDroppable_ActivateEvent
  • QDroppable_CreateEvent
  • QDroppable_DeactivateEvent
  • QDroppable_DropEvent
  • QDroppable_OutEvent
  • QDroppable_OverEvent
  • QDroppableBase
  • QDroppableGen
  • QDropZoneGrouping
  • QEmailAttachment
  • QEmailMessage
  • QEmailServer
  • QEmailStringAttachment
  • QEmailTextBox
  • QEnterKeyEvent
  • QErrorAttribute
  • QEscapeKeyEvent
  • QEvent
  • QFieldset
  • QFile
  • QFileAsset
  • QFileAssetBase
  • QFileAssetDialog
  • QFileAssetType
  • QFileControl
  • QFileFormStateHandler
  • QFilterType
  • QFloatTextBox
  • QFloatTextBox_CodeGenerator
  • QFloatTextBoxBase_CodeGenerator
  • QFocusControlAction
  • QFocusEvent
  • QFocusInEvent
  • QFocusOutEvent
  • QFolder
  • QFontFamily
  • QForm
  • QFormBase
  • QFormGen
  • QFormStateHandler
  • QGridLines
  • QHideCalendarAction
  • QHideDialog
  • QHideDialogBox
  • QHListControl
  • QHListItem
  • QHorizontalAlign
  • QHtml
  • QHtmlAttributeManager
  • QHtmlAttributeManagerBase
  • QHtmlReporter
  • QHtmlTable
  • QHtmlTable_CodeGenerator
  • QHtmlTableBase
  • QHtmlTableCallableColumn
  • QHtmlTableCheckBoxColumn
  • QHtmlTableCheckBoxColumn_ClickEvent
  • QHtmlTableIndexedColumn
  • QHtmlTableLinkColumn
  • QHtmlTableNodeColumn
  • QHtmlTablePropertyColumn
  • QI18n
  • QI18nTests
  • QImageBase
  • QImageBrowser
  • QImageBrowserBase
  • QImageBrowserNav
  • QImageBrowserThumbnails
  • QImageButton
  • QImageControl
  • QImageControlBase
  • QImageFileAsset
  • QImageLabel
  • QImageLabelBase
  • QImageRollover
  • QImageType
  • QIndex
  • QInformixPdoDatabase
  • QInformixPdoDatabaseField
  • QInformixPdoDatabaseResult
  • QInformixPdoDatabaseRow
  • QInputEvent
  • QInstallationValidationResult
  • QInstallationValidator
  • QIntegerTextBox
  • QIntegerTextBox_CodeGenerator
  • QIntegerTextBoxBase_CodeGenerator
  • QJavaScriptAction
  • QJQAction
  • QJQBounceAction
  • QJqButton
  • QJqButton_CreateEvent
  • QJqButtonBase
  • QJqButtonGen
  • QJqCheckBox
  • QJqCheckBox_CreateEvent
  • QJqCheckBoxBase
  • QJqCheckBoxGen
  • QJQHideAction
  • QJQHideEffectAction
  • QJQHighlightAction
  • QJQPulsateAction
  • QJqRadioButton
  • QJqRadioButton_CreateEvent
  • QJqRadioButtonBase
  • QJqRadioButtonGen
  • QJQShakeAction
  • QJQShowAction
  • QJQShowEffectAction
  • QJQSizeAction
  • QJQToggleAction
  • QJQToggleEffectAction
  • QJQTransferAction
  • QJqUiEvent
  • QJqUiPropertyEvent
  • QJsClosure
  • QJsFunction
  • QJsNoQuoteKey
  • QJsParameterList
  • QJsPriority
  • QJsTimer
  • QJsTimerBase
  • QJsVarName
  • QKeyDownEvent
  • QKeyPressEvent
  • QKeyUpEvent
  • QLabel
  • QLabel_CodeGenerator
  • QLabelBase_CodeGenerator
  • QLexer
  • QLinkButton
  • QListBox
  • QListBox_CodeGenerator
  • QListBoxBase
  • QListBoxBase_CodeGenerator
  • QListControl
  • QListControl_CodeGenerator
  • QListControlBase_CodeGenerator
  • QListItem
  • QListItemBase
  • QListItemStyle
  • QManyToManyReference
  • QMenu
  • QMenu_BlurEvent
  • QMenu_CreateEvent
  • QMenu_FocusEvent
  • QMenu_SelectEvent
  • QMenuBase
  • QMenuGen
  • QMimeType
  • QModelConnectorArgumentType
  • QModelConnectorCreateType
  • QModelConnectorEditDlg
  • QModelConnectorOptions
  • QModelConnectorParam
  • QMouseDownEvent
  • QMouseEnterEvent
  • QMouseLeaveEvent
  • QMouseMoveEvent
  • QMouseOutEvent
  • QMouseOverEvent
  • QMouseUpEvent
  • QMultiLevelCacheProvider
  • QMySqlDatabase
  • QMySqlDatabaseField
  • QMySqlDatabaseResult
  • QMySqli5ClusterDatabase
  • QMySqli5Database
  • QMySqli5DatabaseField
  • QMySqli5DatabaseResult
  • QMySqliDatabase
  • QMySqliDatabaseField
  • QMySqliDatabaseResult
  • QMySqliDatabaseRow
  • QNoScriptAjaxAction
  • QNumericTextBox
  • QOnEvent
  • QOracleDatabase
  • QOracleDatabaseField
  • QOracleDatabaseResult
  • QOracleDatabaseRow
  • QOrderedListType
  • QOverflow
  • QPaginatedControl
  • QPaginator
  • QPaginatorBase
  • QPanel
  • QPartialQueryBuilder
  • QPdoDatabase
  • QPdoDatabaseResult
  • QPgConditionILike
  • QPgConditionJsonContains
  • QPgQ
  • QPosition
  • QPostgreSqlDatabase
  • QPostgreSqlDatabaseField
  • QPostgreSqlDatabaseResult
  • QPostgreSqlDatabaseRow
  • QPostgreSqlPdoDatabase
  • QPostgreSqlPdoDatabaseField
  • QPostgreSqlPdoDatabaseResult
  • QPostgreSqlPdoDatabaseRow
  • QProgressbar
  • QProgressbar_ChangeEvent
  • QProgressbar_CompleteEvent
  • QProgressbar_CreateEvent
  • QProgressbarBase
  • QProgressbarGen
  • QQ
  • QQAggregationClause
  • QQAliasTests
  • QQAssociationNode
  • QQAverage
  • QQClause
  • QQColumnNode
  • QQCondition
  • QQConditionAll
  • QQConditionAnd
  • QQConditionBetween
  • QQConditionComparison
  • QQConditionEqual
  • QQConditionExists
  • QQConditionGreaterOrEqual
  • QQConditionGreaterThan
  • QQConditionIn
  • QQConditionIsNotNull
  • QQConditionIsNull
  • QQConditionLessOrEqual
  • QQConditionLessThan
  • QQConditionLike
  • QQConditionLogical
  • QQConditionNone
  • QQConditionNot
  • QQConditionNotBetween
  • QQConditionNotEqual
  • QQConditionNotExists
  • QQConditionNotIn
  • QQConditionNotLike
  • QQConditionOr
  • QQCount
  • QQDistinct
  • QQExpand
  • QQExpandAsArray
  • QQExpandVirtualNode
  • QQFuncTests
  • QQFunctionNode
  • QQGroupBy
  • QQHavingClause
  • QQLimitInfo
  • QQMathNode
  • QQMathOpTests
  • QQMaximum
  • QQMinimum
  • QQNamedValue
  • QQNode
  • QQNoParentNode
  • QQOrderBy
  • QQReverseReferenceNode
  • QQSelect
  • QQSubQueryCountNode
  • QQSubQueryNode
  • QQSubQuerySqlNode
  • QQSum
  • QQTableNode
  • QQuery
  • QQueryBuilder
  • QQueryExpansion
  • QQVirtualNode
  • QRadioButton
  • QRadioButtonList
  • QRadioButtonList_CodeGenerator
  • QRadioButtonListBase_CodeGenerator
  • QRedirectAction
  • QReference
  • QRegex
  • QRegisterClickPositionAction
  • QRepeatDirection
  • QRequestMode
  • QResetTimerAction
  • QResizable
  • QResizable_CreateEvent
  • QResizable_ResizeEvent
  • QResizable_StartEvent
  • QResizable_StopEvent
  • QResizableBase
  • QResizableGen
  • QResizeHandleDirection
  • QRestServiceCodeGen
  • QReverseReference
  • QRssCategory
  • QRssFeed
  • QRssImage
  • QRssItem
  • QSampleControl
  • QSampleTranslation
  • QSelectable
  • QSelectable_CreateEvent
  • QSelectable_SelectedEvent
  • QSelectable_SelectingEvent
  • QSelectable_StartEvent
  • QSelectable_StopEvent
  • QSelectable_UnselectedEvent
  • QSelectable_UnselectingEvent
  • QSelectableBase
  • QSelectableGen
  • QSelectControlAction
  • QSelectEvent
  • QSelectionMode
  • QSelectMenu
  • QSelectMenu_ChangeEvent
  • QSelectMenu_CloseEvent
  • QSelectMenu_CreateEvent
  • QSelectMenu_FocusEvent
  • QSelectMenu_OpenEvent
  • QSelectMenu_SelectEvent
  • QSelectMenuBase
  • QSelectMenuGen
  • QServerAction
  • QServerControlAction
  • QSessionFormStateHandler
  • QSetValueAction
  • QShowCalendarAction
  • QShowDialog
  • QShowDialogBox
  • QSlider
  • QSlider_ChangeEvent
  • QSlider_CodeGenerator
  • QSlider_CreateEvent
  • QSlider_SlideEvent
  • QSlider_StartEvent
  • QSlider_StopEvent
  • QSliderBase
  • QSliderBase_CodeGenerator
  • QSliderGen
  • QSoapMethod
  • QSoapParameter
  • QSoapService
  • QSortable
  • QSortable_ActivateEvent
  • QSortable_BeforeStopEvent
  • QSortable_ChangeEvent
  • QSortable_CreateEvent
  • QSortable_DeactivateEvent
  • QSortable_OutEvent
  • QSortable_OverEvent
  • QSortable_ReceiveEvent
  • QSortable_RemoveEvent
  • QSortable_SortEvent
  • QSortable_StartEvent
  • QSortable_StopEvent
  • QSortable_UpdateEvent
  • QSortableBase
  • QSortableGen
  • QSpinner
  • QSpinner_ChangeEvent
  • QSpinner_CreateEvent
  • QSpinner_SpinEvent
  • QSpinner_StartEvent
  • QSpinner_StopEvent
  • QSpinnerBase
  • QSpinnerGen
  • QSqlColumn
  • QSqLite3PdoDatabase
  • QSqLite3PdoDatabaseField
  • QSqLite3PdoDatabaseResult
  • QSqLite3PdoDatabaseRow
  • QSqlServer2005Database
  • QSqlServer2005DatabaseField
  • QSqlServer2005DatabaseResult
  • QSqlServer2005DatabaseRow
  • QSqlServerDatabase
  • QSqlServerDatabaseField
  • QSqlServerDatabaseResult
  • QSqlServerDatabaseRow
  • QSqlTable
  • QStack
  • QStopPropagationAction
  • QString
  • QStringTest
  • QTabKeyEvent
  • QTabs
  • QTabs_ActivateEvent
  • QTabs_BeforeActivateEvent
  • QTabs_BeforeLoadEvent
  • QTabs_CreateEvent
  • QTabs_LoadEvent
  • QTabsBase
  • QTabsGen
  • QTag
  • QTagStyler
  • QTerminateAction
  • QTestControl
  • QTestForm
  • QTextAlign
  • QTextBox
  • QTextBox_CodeGenerator
  • QTextBoxBase
  • QTextBoxBase_CodeGenerator
  • QTextMode
  • QTimer
  • QTimerExpiredEvent
  • QTimerTests
  • QToggleCssClassAction
  • QToggleDisplayAction
  • QToggleEnableAction
  • QTranslationPoParser
  • QTreeNav
  • QTreeNavItem
  • QType
  • QTypeTable
  • QTypeTests
  • QUnitTestCaseBase
  • QUnorderedListStyle
  • QUpArrowKeyEvent
  • QUrlTextBox
  • QVerticalAlign
  • QVirtualAttributeColumn
  • QWaitIcon
  • QWatcher
  • QWatcherBase
  • QWatcherCache
  • QWatcherDB
  • QWatcherNone
  • QWriteBox
  • RecordsSummary
  • RefreshForm
  • SampleComposite
  • SampleForm
  • SelectableLabel
  • SelectForm
  • SpeedForm
  • TestImageBrowser
  • UrlForm

Interfaces

  • ICacheAction
  • QDataList_CodeGenerator_Interface
  • QTranslationBase

Traits

  • QDataBinder
  • QListItemManager
  • QModelTrait

Exceptions

  • QCallerException
  • QCrossScriptingException
  • QCryptographyException
  • QDatabaseExceptionBase
  • QDataBindException
  • QDateTimeNullException
  • QEmailException
  • QIndexOutOfRangeException
  • QInformixPdoDatabaseException
  • QInvalidCastException
  • QInvalidFormStateException
  • QMySqliDatabaseException
  • QOptimisticLockingException
  • QOracleDatabaseException
  • QPdoDatabaseException
  • QPoParserException
  • QPostgreSqlDatabaseException
  • QPostgreSqlPdoDatabaseException
  • QRemoteAdminDeniedException
  • QSqLite3PdoDatabaseException
  • QSqlServer2005DatabaseException
  • QSqlServerDatabaseException
  • QUndefinedMethodException
  • QUndefinedPrimaryKeyException
  • QUndefinedPropertyException

Functions

  • __database_check_error
  • __QForm_EvaluateTemplate_ObHandler
  • _b
  • _indent
  • _nl
  • _p
  • _r
  • _t
  • _tp
  • _tr
  • array_trim
  • beginsWith
  • CamelCaseFromDash
  • CastToInt
  • DataGridEvalHandleError
  • DisplayMonospacedText
  • endsWith
  • GO_BACK
  • jq_anytime_gen
  • jq_control_gen
  • jq_inc_gen
  • jq_indent
  • PrintExplainStatement
  • PrintInstructions
  • QcubedHandleCodeGenParseError
  • QcubedHandleError
  • QcubedHandleException
  • QCubedShutdown
  • QDateTimeErrorHandler
  • trimOffEnd
  • trimOffFront
  • Overview
  • Package
  • Class
   1: <?php
   2: 
   3:     function QcubedHandleCodeGenParseError($__exc_errno, $__exc_errstr, $__exc_errfile, $__exc_errline) {
   4:         $strErrorString = str_replace("SimpleXMLElement::__construct() [<a href='function.SimpleXMLElement---construct'>function.SimpleXMLElement---construct</a>]: ", '', $__exc_errstr);
   5:         QCodeGen::$RootErrors .= sprintf("%s\r\n", $strErrorString);
   6:     }
   7: 
   8:     function GO_BACK($intNumChars) {
   9:         $content_so_far = ob_get_contents();
  10:         ob_end_clean();
  11:         $content_so_far = substr($content_so_far, 0, strlen($content_so_far) - $intNumChars);
  12:         ob_start();
  13:         print $content_so_far;
  14:     }
  15: 
  16:     // returns true if $str begins with $sub
  17:     function beginsWith( $str, $sub ) {
  18:         return ( substr( $str, 0, strlen( $sub ) ) == $sub );
  19:     }
  20: 
  21:     // return tru if $str ends with $sub
  22:     function endsWith( $str, $sub ) {
  23:         return ( substr( $str, strlen( $str ) - strlen( $sub ) ) == $sub );
  24:     }
  25: 
  26:     // trims off x chars from the front of a string
  27:     // or the matching string in $off is trimmed off
  28:     function trimOffFront( $off, $str ) {
  29:         if( is_numeric( $off ) )
  30:             return substr( $str, $off );
  31:         else
  32:             return substr( $str, strlen( $off ) );
  33:     }
  34: 
  35:     // trims off x chars from the end of a string
  36:     // or the matching string in $off is trimmed off
  37:     function trimOffEnd( $off, $str ) {
  38:         if( is_numeric( $off ) )
  39:             return substr( $str, 0, strlen( $str ) - $off );
  40:         else
  41:             return substr( $str, 0, strlen( $str ) - strlen( $off ) );
  42:     }
  43: 
  44:     /**
  45:      * This is the CodeGen class which performs the code generation
  46:      * for both the Object-Relational Model (e.g. Data Objects) as well as
  47:      * the draft Forms, which make up simple HTML/PHP scripts to perform
  48:      * basic CRUD functionality on each object.
  49:      * @package Codegen
  50:      * @property string $Errors List of errors
  51:      * @property string $Warnings List of warnings
  52:      */
  53:     abstract class QCodeGenBase extends QBaseClass {
  54:         // Class Name Suffix/Prefix
  55:         /** @var string Class Prefix, as specified in the codegen_settings.xml file */
  56:         protected $strClassPrefix;
  57:         /** @var string Class suffix, as specified in the codegen_settings.xml file */
  58:         protected $strClassSuffix;
  59: 
  60:         /** @var string Errors and Warnings collected during the process of codegen **/
  61:         protected $strErrors;
  62: 
  63:         /** @var string Warnings collected during the codegen process. */
  64:         protected $strWarnings;
  65: 
  66:         /**
  67:          * PHP Reserved Words.  They make up:
  68:          * Invalid Type names -- these are reserved words which cannot be Type names in any user type table
  69:          * Invalid Table names -- these are reserved words which cannot be used as any table name
  70:          * Please refer to : http://php.net/manual/en/reserved.php
  71:          */
  72:         const PhpReservedWords = 'new, null, break, return, switch, self, case, const, clone, continue, declare, default, echo, else, elseif, empty, exit, eval, if, try, throw, catch, public, private, protected, function, extends, foreach, for, while, do, var, class, static, abstract, isset, unset, implements, interface, instanceof, include, include_once, require, require_once, abstract, and, or, xor, array, list, false, true, global, parent, print, exception, namespace, goto, final, endif, endswitch, enddeclare, endwhile, use, as, endfor, endforeach, this';
  73: 
  74:         /**
  75:          * @var array The list of template base paths to search, in order, when looking for a particular template. Set this
  76:          * to insert new template paths. If not set, the default will be the project template path, following by the qcubed core path.
  77:          */
  78:         public static $TemplatePaths;
  79: 
  80:         /**
  81:          * DebugMode -- for Template Developers
  82:          * This will output the current evaluated template/statement to the screen
  83:          * On "eval" errors, you can click on the "View Rendered Page" to see what currently
  84:          * is being evaluated, which should hopefully aid in template debugging.
  85:          */
  86:         const DebugMode = false;
  87: 
  88:         /**
  89:          * This static array contains an array of active and executed codegen objects, based
  90:          * on the XML Configuration passed in to Run()
  91:          *
  92:          * @var QCodeGen[] array of active/executed codegen objects
  93:          */
  94:         public static $CodeGenArray;
  95: 
  96:         /**
  97:          * This is the array representation of the parsed SettingsXml
  98:          * for reportback purposes.
  99:          *
 100:          * @var string[] array of config settings
 101:          */
 102:         protected static $SettingsXmlArray;
 103: 
 104:         /**
 105:          * This is the SimpleXML representation of the Settings XML file
 106:          *
 107:          * @var SimpleXmlElement the XML representation
 108:          */
 109:         protected static $SettingsXml;
 110: 
 111:         public static $SettingsFilePath;
 112: 
 113:         /**
 114:          * Application Name (from CodeGen Settings)
 115:          *
 116:          * @var string $ApplicationName
 117:          */
 118:         public static $ApplicationName;
 119: 
 120:         /**
 121:          * Preferred Render Method (from CodeGen Settings)
 122:          *
 123:          * @var string $PreferredRenderMethod
 124:          */
 125:         public static $PreferredRenderMethod;
 126: 
 127:         /**
 128:          * Create Method (from CodeGen Settings)
 129:          *
 130:          * @var string $CreateMethod
 131:          */
 132:         public static $CreateMethod;
 133: 
 134:         /**
 135:          * Default Button Class (from CodeGen Settings)
 136:          *
 137:          * @var string $DefaultButtonClass
 138:          */
 139:         public static $DefaultButtonClass;
 140: 
 141: 
 142:         /**
 143:          * Template Escape Begin (from CodeGen Settings)
 144:          *
 145:          * @var string $TemplateEscapeBegin
 146:          */
 147:         protected static $TemplateEscapeBegin;
 148:         protected static $TemplateEscapeBeginLength;
 149: 
 150:         /**
 151:          * Template Escape End (from CodeGen Settings)
 152:          *
 153:          * @var string $TemplateEscapeEnd
 154:          */
 155:         protected static $TemplateEscapeEnd;
 156:         protected static $TemplateEscapeEndLength;
 157: 
 158:         public static $RootErrors = '';
 159: 
 160:         /**
 161:          * @var string[] array of directories to be excluded in codegen (lower cased)
 162:          * @access protected
 163:          */
 164:         protected static $DirectoriesToExcludeArray = array('.','..','.svn','svn','cvs','.git');
 165: 
 166:         /**
 167:          * Gets the settings in codegen_settings.xml file and returns its text without comments
 168:          * @return string
 169:          */
 170:         public static function GetSettingsXml() {
 171:             $strCrLf = "\r\n";
 172: 
 173:             $strToReturn = sprintf('<codegen>%s', $strCrLf);
 174:             $strToReturn .= sprintf('   <name application="%s"/>%s', QCodeGen::$ApplicationName, $strCrLf);
 175:             $strToReturn .= sprintf('   <templateEscape begin="%s" end="%s"/>%s', QCodeGen::$TemplateEscapeBegin, QCodeGen::$TemplateEscapeEnd, $strCrLf);
 176:             $strToReturn .= sprintf('   <render preferredRenderMethod="%s"/>%s', QCodeGen::$PreferredRenderMethod, $strCrLf);
 177:             $strToReturn .= sprintf('   <dataSources>%s', $strCrLf);
 178:             foreach (QCodeGen::$CodeGenArray as $objCodeGen)
 179:                 $strToReturn .= $strCrLf . $objCodeGen->GetConfigXml();
 180:             $strToReturn .= sprintf('%s </dataSources>%s', $strCrLf, $strCrLf);
 181:             $strToReturn .= '</codegen>';
 182: 
 183:             return $strToReturn;
 184:         }
 185: 
 186:         /**
 187:          * The function which actually performs the steps for code generation
 188:          * Code generation begins here.
 189:          * @param string $strSettingsXmlFilePath Path to the settings file
 190:          */
 191:         public static function Run($strSettingsXmlFilePath) {
 192:             define ('__CODE_GENERATING__', true);
 193:             QCodeGen::$CodeGenArray = array();
 194:             QCodeGen::$SettingsFilePath = $strSettingsXmlFilePath;
 195: 
 196:             if (!file_exists($strSettingsXmlFilePath)) {
 197:                 QCodeGen::$RootErrors = 'FATAL ERROR: CodeGen Settings XML File (' . $strSettingsXmlFilePath . ') was not found.';
 198:                 return;
 199:             }
 200: 
 201:             if (!is_file($strSettingsXmlFilePath)) {
 202:                 QCodeGen::$RootErrors = 'FATAL ERROR: CodeGen Settings XML File (' . $strSettingsXmlFilePath . ') was not found.';
 203:                 return;
 204:             }
 205: 
 206:             // Try Parsing the Xml Settings File
 207:             try {
 208:                 QApplication::SetErrorHandler('QcubedHandleCodeGenParseError', E_ALL);
 209:                 QCodeGen::$SettingsXml = new SimpleXMLElement(file_get_contents($strSettingsXmlFilePath));
 210:                 QApplication::RestoreErrorHandler();
 211:             } catch (Exception $objExc) {
 212:                 QCodeGen::$RootErrors .= 'FATAL ERROR: Unable to parse CodeGenSettings XML File: ' . $strSettingsXmlFilePath;
 213:                 QCodeGen::$RootErrors .= "\r\n";
 214:                 QCodeGen::$RootErrors .= $objExc->getMessage();
 215:                 return;
 216:             }
 217: 
 218:             // Set the Template Escaping
 219:             QCodeGen::$TemplateEscapeBegin = QCodeGen::LookupSetting(QCodeGen::$SettingsXml, 'templateEscape', 'begin');
 220:             QCodeGen::$TemplateEscapeEnd = QCodeGen::LookupSetting(QCodeGen::$SettingsXml, 'templateEscape', 'end');
 221:             QCodeGen::$TemplateEscapeBeginLength = strlen(QCodeGen::$TemplateEscapeBegin);
 222:             QCodeGen::$TemplateEscapeEndLength = strlen(QCodeGen::$TemplateEscapeEnd);
 223: 
 224:             if ((!QCodeGen::$TemplateEscapeBeginLength) || (!QCodeGen::$TemplateEscapeEndLength)) {
 225:                 QCodeGen::$RootErrors .= "CodeGen Settings XML Fatal Error: templateEscape begin and/or end was not defined\r\n";
 226:                 return;
 227:             }
 228: 
 229:             // Application Name
 230:             QCodeGen::$ApplicationName = QCodeGen::LookupSetting(QCodeGen::$SettingsXml, 'name', 'application');
 231: 
 232:             // Codegen Defaults
 233:             QCodeGen::$PreferredRenderMethod = QCodeGen::LookupSetting(QCodeGen::$SettingsXml, 'formgen', 'preferredRenderMethod');
 234:             QCodeGen::$CreateMethod = QCodeGen::LookupSetting(QCodeGen::$SettingsXml, 'formgen', 'createMethod');
 235:             QCodeGen::$DefaultButtonClass = QCodeGen::LookupSetting(QCodeGen::$SettingsXml, 'formgen', 'buttonClass');
 236: 
 237:             if (!QCodeGen::$DefaultButtonClass) {
 238:                 QCodeGen::$RootErrors .= "CodeGen Settings XML Fatal Error: buttonClass was not defined\r\n";
 239:                 return;
 240:             }
 241: 
 242:             // Iterate Through DataSources
 243:             if (QCodeGen::$SettingsXml->dataSources->asXML())
 244:                 foreach (QCodeGen::$SettingsXml->dataSources->children() as $objChildNode) {
 245:                     switch (dom_import_simplexml($objChildNode)->nodeName) {
 246:                         case 'database':
 247:                             QCodeGen::$CodeGenArray[] = new QDatabaseCodeGen($objChildNode);
 248:                             break;
 249:                         case 'restService':
 250:                             QCodeGen::$CodeGenArray[] = new QRestServiceCodeGen($objChildNode);
 251:                             break;
 252:                         default:
 253:                             QCodeGen::$RootErrors .= sprintf("Invalid Data Source Type in CodeGen Settings XML File (%s): %s\r\n",
 254:                                 $strSettingsXmlFilePath, dom_import_simplexml($objChildNode)->nodeName);
 255:                             break;
 256:                     }
 257:                 }
 258:         }
 259: 
 260:         /**
 261:          * This will lookup either the node value (if no attributename is passed in) or the attribute value
 262:          * for a given Tag.  Node Searches only apply from the root level of the configuration XML being passed in
 263:          * (e.g. it will not be able to lookup the tag name of a grandchild of the root node)
 264:          *
 265:          * If No Tag Name is passed in, then attribute/value lookup is based on the root node, itself.
 266:          *
 267:          * @param SimpleXmlElement $objNode
 268:          * @param string $strTagName
 269:          * @param string $strAttributeName
 270:          * @param string $strType
 271:          * @return mixed the return type depends on the QType you pass in to $strType
 272:          */
 273:         static public function LookupSetting($objNode, $strTagName, $strAttributeName = null, $strType = QType::String) {
 274:             if ($strTagName)
 275:                 $objNode = $objNode->$strTagName;
 276: 
 277:             if ($strAttributeName) {
 278:                 switch ($strType) {
 279:                     case QType::Integer:
 280:                         try {
 281:                             $intToReturn = QType::Cast($objNode[$strAttributeName], QType::Integer);
 282:                             return $intToReturn;
 283:                         } catch (Exception $objExc) {
 284:                             return null;
 285:                         }
 286:                     case QType::Boolean:
 287:                         try {
 288:                             $blnToReturn = QType::Cast($objNode[$strAttributeName], QType::Boolean);
 289:                             return $blnToReturn;
 290:                         } catch (Exception $objExc) {
 291:                             return null;
 292:                         }
 293:                     default:
 294:                         $strToReturn = trim(QType::Cast($objNode[$strAttributeName], QType::String));
 295:                         return $strToReturn;
 296:                 }
 297:             } else {
 298:                 $strToReturn = trim(QType::Cast($objNode, QType::String));
 299:                 return $strToReturn;
 300:             }
 301:         }
 302: 
 303:         /**
 304:          *
 305:          * @return array
 306:          */
 307:         public static function GenerateAggregate() {
 308:             $objDbOrmCodeGen = array();
 309:             $objRestServiceCodeGen = array();
 310: 
 311:             foreach (QCodeGen::$CodeGenArray as $objCodeGen) {
 312:                 if ($objCodeGen instanceof QDatabaseCodeGen)
 313:                     array_push($objDbOrmCodeGen, $objCodeGen);
 314:                 if ($objCodeGen instanceof QRestServiceCodeGen)
 315:                     array_push($objRestServiceCodeGen, $objCodeGen);
 316:             }
 317: 
 318:             $strToReturn = array();
 319:             array_merge($strToReturn, QDatabaseCodeGen::GenerateAggregateHelper($objDbOrmCodeGen));
 320: //          array_push($strToReturn, QRestServiceCodeGen::GenerateAggregateHelper($objRestServiceCodeGen));
 321: 
 322:             return $strToReturn;
 323:         }
 324: 
 325:         /**
 326:          * Given a template prefix (e.g. db_orm_, db_type_, rest_, soap_, etc.), pull
 327:          * all the _*.tpl templates from any subfolders of the template prefix
 328:          * in QCodeGen::TemplatesPath and QCodeGen::TemplatesPathCustom,
 329:          * and call GenerateFile() on each one.  If there are any template files that reside
 330:          * in BOTH TemplatesPath AND TemplatesPathCustom, then only use the TemplatesPathCustom one (which
 331:          * in essence overrides the one in TemplatesPath)
 332:          *
 333:          * @param string  $strTemplatePrefix the prefix of the templates you want to generate against
 334:          * @param mixed[] $mixArgumentArray  array of arguments to send to EvaluateTemplate
 335:          *
 336:          * @throws Exception
 337:          * @throws QCallerException
 338:          * @return boolean success/failure on whether or not all the files generated successfully
 339:          */
 340:         public function GenerateFiles($strTemplatePrefix, $mixArgumentArray) {
 341:             // If you are editing core templates, and getting EOF errors only on the travis build, this may be your problem. Scan your files and remove short tags.
 342:             if (QCodeGen::DebugMode && ini_get ('short_open_tag')) _p("Warning: PHP directive short_open_tag is on. Using short tags will cause unexpected EOF on travis build.\n", false);
 343: 
 344:             // Default the template paths
 345:             if (!static::$TemplatePaths) {
 346:                 static::$TemplatePaths = array (
 347:                     __QCUBED_CORE__ . '/codegen/templates/',
 348:                     __QCUBED__ . '/codegen/templates/'
 349:                 );
 350:             }
 351: 
 352:             // validate the template paths
 353:             foreach (static::$TemplatePaths as $strPath) {
 354:                 if (!is_dir($strPath)) {
 355:                     throw new Exception(sprintf("Template path: %s does not appear to be a valid directory.", $strPath));
 356:                 }
 357:             }
 358: 
 359:             // Create an array of arrays of standard templates and custom (override) templates to process
 360:             // Index by [module_name][filename] => true/false where
 361:             // module name (e.g. "class_gen", "form_delegates) is name of folder within the prefix (e.g. "db_orm")
 362:             // filename is the template filename itself (in a _*.tpl format)
 363:             // true = override (use custom) and false = do not override (use standard)
 364:             $strTemplateArray = array();
 365: 
 366:             // Go through standard templates first, then override in order
 367:             foreach (static::$TemplatePaths as $strPath) {
 368:                 $this->buildTemplateArray($strPath . $strTemplatePrefix, $strTemplateArray);
 369:             }
 370: 
 371:             // Finally, iterate through all the TemplateFiles and call GenerateFile to Evaluate/Generate/Save them
 372:             $blnSuccess = true;
 373:             foreach ($strTemplateArray as $strModuleName => $strFileArray) {
 374:                 foreach ($strFileArray as $strFilename => $strPath) {
 375:                     if (!$this->GenerateFile($strTemplatePrefix . '/' . $strModuleName, $strPath, $mixArgumentArray)) {
 376:                         $blnSuccess = false;
 377:                     }
 378:                 }
 379:             }
 380: 
 381:             return $blnSuccess;
 382:         }
 383: 
 384:         protected function buildTemplateArray ($strTemplateFilePath, &$strTemplateArray) {
 385:             if (!$strTemplateFilePath) return;
 386:             if (substr( $strTemplateFilePath, -1 ) != '/') {
 387:                 $strTemplateFilePath .= '/';
 388:             }
 389:             if (is_dir($strTemplateFilePath)) {
 390:                 $objDirectory = opendir($strTemplateFilePath);
 391:                 while ($strModuleName = readdir($objDirectory)) {
 392:                     if (!in_array(strtolower($strModuleName), QCodeGen::$DirectoriesToExcludeArray) &&
 393:                             is_dir($strTemplateFilePath . $strModuleName)) {
 394:                         $objModuleDirectory = opendir($strTemplateFilePath . $strModuleName);
 395:                         while ($strFilename = readdir($objModuleDirectory)) {
 396:                             if ((QString::FirstCharacter($strFilename) == '_') &&
 397:                                 (substr($strFilename, strlen($strFilename) - 8) == '.tpl.php')
 398:                             ) {
 399:                                 $strTemplateArray[$strModuleName][$strFilename] = $strTemplateFilePath . $strModuleName . '/' . $strFilename;
 400:                             }
 401:                         }
 402:                     }
 403:                 }
 404:             }
 405:         }
 406: 
 407:         /**
 408:          * Returns the settings of the template file as SimpleXMLElement object
 409:          *
 410:          * @param null|string $strTemplateFilePath Path to the file
 411:          * @param null|string $strTemplate         Text of the template (if $strTemplateFilePath is null, this field must be string)
 412:          * @deprecated
 413:          *
 414:          * @return SimpleXMLElement
 415:          * @throws Exception
 416:          */
 417:         protected function getTemplateSettings($strTemplateFilePath, &$strTemplate = null) {
 418:             if ($strTemplate === null)
 419:                 $strTemplate = file_get_contents($strTemplateFilePath);
 420:             $strError = 'Template\'s first line must be <template OverwriteFlag="boolean" DocrootFlag="boolean" TargetDirectory="string" DirectorySuffix="string" TargetFileName="string"/>: ' . $strTemplateFilePath;
 421:             // Parse out the first line (which contains path and overwriting information)
 422:             $intPosition = strpos($strTemplate, "\n");
 423:             if ($intPosition === false) {
 424:                 throw new Exception($strError);
 425:             }
 426: 
 427:             $strFirstLine = trim(substr($strTemplate, 0, $intPosition));
 428: 
 429:             $objTemplateXml = null;
 430:             // Attempt to Parse the First Line as XML
 431:             try {
 432:                 @$objTemplateXml = new SimpleXMLElement($strFirstLine);
 433:             } catch (Exception $objExc) {}
 434: 
 435:             if (is_null($objTemplateXml) || (!($objTemplateXml instanceof SimpleXMLElement)))
 436:                 throw new Exception($strError);
 437:             $strTemplate = substr($strTemplate, $intPosition + 1);
 438:             return $objTemplateXml;
 439:         }
 440: 
 441:         /**
 442:          * Generates a php code using a template file
 443:          *
 444:          * @param string  $strModuleSubPath
 445:          * @param string  $strTemplateFilePath Path to the template file
 446:          * @param mixed[] $mixArgumentArray
 447:          * @param boolean $blnSave             whether or not to actually perform the save
 448:          *
 449:          * @throws QCallerException
 450:          * @throws Exception
 451:          * @return mixed returns the evaluated template or boolean save success.
 452:          */
 453:         public function GenerateFile($strModuleSubPath, $strTemplateFilePath, $mixArgumentArray, $blnSave = true) {
 454:             // Setup Debug/Exception Message
 455:             if (QCodeGen::DebugMode) _p("Evaluating $strTemplateFilePath<br/>", false);
 456: 
 457:             // Check to see if the template file exists, and if it does, Load It
 458:             if (!file_exists($strTemplateFilePath))
 459:                 throw new QCallerException('Template File Not Found: ' . $strTemplateFilePath);
 460: 
 461:             // Evaluate the Template
 462:             // make sure paths are set up to pick up included files from the various directories.
 463:             // Must be the reverse of the buildTemplateArray order
 464:             $a = array();
 465:             foreach (static::$TemplatePaths as $strTemplatePath) {
 466:                 array_unshift($a,  $strTemplatePath . $strModuleSubPath);
 467:             }
 468:             $strSearchPath = implode (PATH_SEPARATOR, $a) . PATH_SEPARATOR . get_include_path();
 469:             $strOldIncludePath = set_include_path ($strSearchPath);
 470:             if ($strSearchPath != get_include_path()) {
 471:                 throw new QCallerException ('Can\'t override include path. Make sure your apache or server settings allow include paths to be overridden. ' );
 472:             }
 473: 
 474:             $strTemplate = $this->EvaluatePHP($strTemplateFilePath, $mixArgumentArray, $templateSettings);
 475:             set_include_path($strOldIncludePath);
 476: 
 477:             $blnOverwriteFlag = QType::Cast($templateSettings['OverwriteFlag'], QType::Boolean);
 478:             $blnDocrootFlag = QType::Cast($templateSettings['DocrootFlag'], QType::Boolean);
 479:             $strTargetDirectory = QType::Cast($templateSettings['TargetDirectory'], QType::String);
 480:             $strDirectorySuffix = QType::Cast($templateSettings['DirectorySuffix'], QType::String);
 481:             $strTargetFileName = QType::Cast($templateSettings['TargetFileName'], QType::String);
 482: 
 483:             if (is_null($blnOverwriteFlag) || is_null($strTargetFileName) || is_null($strTargetDirectory) || is_null($strDirectorySuffix) || is_null($blnDocrootFlag))  {
 484:                 throw new Exception('the template settings cannot be null');
 485:             }
 486: 
 487:             if ($blnSave && $strTargetDirectory) {
 488:                 // Figure out the REAL target directory
 489:                 if ($blnDocrootFlag)
 490:                     $strTargetDirectory = __DOCROOT__ . $strTargetDirectory . $strDirectorySuffix;
 491:                 else
 492:                     $strTargetDirectory = $strTargetDirectory . $strDirectorySuffix;
 493: 
 494:                 // Create Directory (if needed)
 495:                 if (!is_dir($strTargetDirectory))
 496:                     if (!QApplication::MakeDirectory($strTargetDirectory, 0777))
 497:                         throw new Exception('Unable to mkdir ' . $strTargetDirectory);
 498: 
 499:                 // Save to Disk
 500:                 $strFilePath = sprintf('%s/%s', $strTargetDirectory, $strTargetFileName);
 501:                 if ($blnOverwriteFlag || (!file_exists($strFilePath))) {
 502:                     $intBytesSaved = file_put_contents($strFilePath, $strTemplate);
 503: 
 504:                     $this->setGeneratedFilePermissions($strFilePath);
 505:                     return ($intBytesSaved == strlen($strTemplate));
 506:                 } else
 507:                     // Becuase we are not supposed to overwrite, we should return "true" by default
 508:                     return true;
 509:             }
 510: 
 511:             // Why Did We Not Save?
 512:             if ($blnSave) {
 513:                 // We WANT to Save, but QCubed Configuration says that this functionality/feature should no longer be generated
 514:                 // By definition, we should return "true"
 515:                 return true;
 516:             }
 517:             // Running GenerateFile() specifically asking it not to save -- so return the evaluated template instead
 518:             return $strTemplate;
 519:         }
 520: 
 521:         /**
 522:          * Sets the file permissions (Linux only) for a file generated by the Code Generator
 523:          * @param string $strFilePath Path of the generated file
 524:          *
 525:          * @throws QCallerException
 526:          */
 527:         protected function setGeneratedFilePermissions($strFilePath) {
 528:             // CHMOD to full read/write permissions (applicable only to nonwindows)
 529:             // Need to ignore error handling for this call just in case
 530:             if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
 531:                 QApplication::SetErrorHandler(null);
 532:                 chmod($strFilePath, 0666);
 533:                 QApplication::RestoreErrorHandler();
 534:             }
 535:         }
 536: 
 537:         /**
 538:          * Returns the evaluated PHP
 539:          *
 540:          * @param $strFilename
 541:          * @param $mixArgumentArray
 542:          * @param null $templateSettings
 543:          * @return mixed|string
 544:          */
 545:         protected function EvaluatePHP($strFilename, $mixArgumentArray, &$templateSettings = null)  {
 546:             // Get all the arguments and set them locally
 547:             if ($mixArgumentArray) foreach ($mixArgumentArray as $strName=>$mixValue) {
 548:                 $$strName = $mixValue;
 549:             }
 550:             global $_TEMPLATE_SETTINGS;
 551:             unset($_TEMPLATE_SETTINGS);
 552:             $_TEMPLATE_SETTINGS = null;
 553: 
 554:             // Of course, we also need to locally allow "objCodeGen"
 555:             $objCodeGen = $this;
 556: 
 557:             // Get Database Escape Identifiers
 558:             $strEscapeIdentifierBegin = QApplication::$Database[$this->intDatabaseIndex]->EscapeIdentifierBegin;
 559:             $strEscapeIdentifierEnd = QApplication::$Database[$this->intDatabaseIndex]->EscapeIdentifierEnd;
 560: 
 561:             // Store the Output Buffer locally
 562:             $strAlreadyRendered = ob_get_contents();
 563: 
 564:             if (ob_get_level()) ob_clean();
 565:             ob_start();
 566:             include($strFilename);
 567:             $strTemplate = ob_get_contents();
 568:             ob_end_clean();
 569: 
 570:             $templateSettings = $_TEMPLATE_SETTINGS;
 571:             unset($_TEMPLATE_SETTINGS);
 572: 
 573:             // Restore the output buffer and return evaluated template
 574:             print($strAlreadyRendered);
 575: 
 576:             // Remove all \r from the template (for Win/*nix compatibility)
 577:             $strTemplate = str_replace("\r", '', $strTemplate);
 578:             return $strTemplate;
 579:         }
 580: 
 581:         ///////////////////////
 582:         // COMMONLY OVERRIDDEN CONVERSION FUNCTIONS
 583:         ///////////////////////
 584: 
 585:         /**
 586:          * Given a table name, returns the name of the class for the corresponding model object.
 587:          *
 588:          * @param string $strTableName
 589:          * @return string
 590:          */
 591:         protected function ModelClassName($strTableName) {
 592:             $strTableName = $this->StripPrefixFromTable($strTableName);
 593:             return sprintf('%s%s%s',
 594:                 $this->strClassPrefix,
 595:                 QConvertNotation::CamelCaseFromUnderscore($strTableName),
 596:                 $this->strClassSuffix);
 597:         }
 598: 
 599:         /**
 600:          * Given a table name, returns a variable name that will be used to represent the corresponding model object.
 601:          * @param string $strTableName
 602:          * @return string
 603:          */
 604:         public function ModelVariableName($strTableName) {
 605:             $strTableName = $this->StripPrefixFromTable($strTableName);
 606:             return QConvertNotation::PrefixFromType(QType::Object) .
 607:             QConvertNotation::CamelCaseFromUnderscore($strTableName);
 608:         }
 609: 
 610:         /**
 611:          * Given a table name, returns the variable name that will be used to refer to the object in a
 612:          * reverse reference context (many-to-one).
 613:          * @param string $strTableName
 614:          * @return string
 615:          */
 616:         protected function ModelReverseReferenceVariableName($strTableName) {
 617:             $strTableName = $this->StripPrefixFromTable($strTableName);
 618:             return $this->ModelVariableName($strTableName);
 619:         }
 620: 
 621:         /**
 622:          * Given a table name, returns the variable type of the object in a
 623:          * reverse reference context (many-to-one).
 624:          * @param $strTableName
 625:          * @return string
 626:          */
 627:         protected function ModelReverseReferenceVariableType($strTableName) {
 628:             $strTableName = $this->StripPrefixFromTable($strTableName);
 629:             return $this->ModelClassName($strTableName);
 630:         }
 631: 
 632: 
 633:         /**
 634:          * Given a column, returns the name of the variable used to represent the column's value inside
 635:          * the model object.
 636:          *
 637:          * @param QSqlColumn $objColumn
 638:          * @return string
 639:          */
 640:         protected function ModelColumnVariableName(QSqlColumn $objColumn) {
 641:             return QConvertNotation::PrefixFromType($objColumn->VariableType) .
 642:                 QConvertNotation::CamelCaseFromUnderscore($objColumn->Name);
 643:         }
 644: 
 645:         /**
 646:          * Return the name of the property corresponding to the given column name as used in the getter and setter of
 647:          * the model object.
 648:          * @param string $strColumnName
 649:          * @return string
 650:          */
 651:         protected function ModelColumnPropertyName($strColumnName) {
 652:             return QConvertNotation::CamelCaseFromUnderscore($strColumnName);
 653:         }
 654: 
 655:         /**
 656:          * Return the name of the property corresponding to the given column name as used in the getter and setter of
 657:          * a Type object.
 658:          * @param string $strColumnName Column name
 659:          * @return string
 660:          */
 661:         protected function TypeColumnPropertyName($strColumnName) {
 662:             return QConvertNotation::CamelCaseFromUnderscore($strColumnName);
 663:         }
 664: 
 665:         /**
 666:          * Given the name of a column that is a foreign key to another table, returns a kind of
 667:          * virtual column name that would refer to the object pointed to. This new name is not actually used, but derivatives
 668:          * of this name are used to represent a variable and property name that refers to this object that will get stored
 669:          * in the model.
 670:          *
 671:          * @param string $strColumnName
 672:          * @return string
 673:          */
 674:         protected function ModelReferenceColumnName($strColumnName) {
 675:             $intNameLength = strlen($strColumnName);
 676: 
 677:             // Does the column name for this reference column end in "_id"?
 678:             if (($intNameLength > 3) && (substr($strColumnName, $intNameLength - 3) == "_id")) {
 679:                 // It ends in "_id" but we don't want to include the "Id" suffix
 680:                 // in the Variable Name.  So remove it.
 681:                 $strColumnName = substr($strColumnName, 0, $intNameLength - 3);
 682:             } else {
 683:                 // Otherwise, let's add "_object" so that we don't confuse this variable name
 684:                 // from the variable that was mapped from the physical database
 685:                 // E.g., if it's a numeric FK, and the column is defined as "person INT",
 686:                 // there will end up being two variables, one for the Person id integer, and
 687:                 // one for the Person object itself.  We'll add Object t o the name of the Person object
 688:                 // to make this deliniation.
 689:                 $strColumnName = sprintf("%s_object", $strColumnName);
 690:             }
 691: 
 692:             return $strColumnName;
 693:         }
 694: 
 695:         /**
 696:          * Given a column name to a foreign key, returns the name of the variable that will represent the foreign object
 697:          * stored in the model.
 698:          *
 699:          * @param string $strColumnName
 700:          * @return string
 701:          */
 702:         protected function ModelReferenceVariableName($strColumnName) {
 703:             $strColumnName = $this->ModelReferenceColumnName($strColumnName);
 704:             return QConvertNotation::PrefixFromType(QType::Object) .
 705:                 QConvertNotation::CamelCaseFromUnderscore($strColumnName);
 706:         }
 707: 
 708:         /**
 709:          * Given a column name to a foreign key, returns the name of the property that will be used in the getter and setter
 710:          * to represent the foreign object stored in the model.
 711:          *
 712:          * @param string $strColumnName
 713:          * @return string
 714:          */
 715:         protected function ModelReferencePropertyName($strColumnName) {
 716:             $strColumnName = $this->ModelReferenceColumnName($strColumnName);
 717:             return QConvertNotation::CamelCaseFromUnderscore($strColumnName);
 718:         }
 719: 
 720:         protected function ParameterCleanupFromColumn(QSqlColumn $objColumn, $blnIncludeEquality = false) {
 721:             if ($blnIncludeEquality)
 722:                 return sprintf('$%s = $objDatabase->SqlVariable($%s, true);',
 723:                     $objColumn->VariableName, $objColumn->VariableName);
 724:             else
 725:                 return sprintf('$%s = $objDatabase->SqlVariable($%s);',
 726:                     $objColumn->VariableName, $objColumn->VariableName);
 727:         }
 728: 
 729:         // To be used to list the columns as input parameters, or as parameters for sprintf
 730:         protected function ParameterListFromColumnArray($objColumnArray) {
 731:             return $this->ImplodeObjectArray(', ', '$', '', 'VariableName', $objColumnArray);
 732:         }
 733: 
 734:         protected function ImplodeObjectArray($strGlue, $strPrefix, $strSuffix, $strProperty, $objArrayToImplode) {
 735:             $strArrayToReturn = array();
 736:             if ($objArrayToImplode) foreach ($objArrayToImplode as $objObject) {
 737:                 array_push($strArrayToReturn, sprintf('%s%s%s', $strPrefix, $objObject->__get($strProperty), $strSuffix));
 738:             }
 739: 
 740:             return implode($strGlue, $strArrayToReturn);
 741:         }
 742: 
 743:         protected function TypeTokenFromTypeName($strName) {
 744:             $strToReturn = '';
 745:             for($intIndex = 0; $intIndex < strlen($strName); $intIndex++)
 746:                 if (((ord($strName[$intIndex]) >= ord('a')) &&
 747:                      (ord($strName[$intIndex]) <= ord('z'))) ||
 748:                     ((ord($strName[$intIndex]) >= ord('A')) &&
 749:                      (ord($strName[$intIndex]) <= ord('Z'))) ||
 750:                     ((ord($strName[$intIndex]) >= ord('0')) &&
 751:                      (ord($strName[$intIndex]) <= ord('9'))) ||
 752:                     ($strName[$intIndex] == '_'))
 753:                     $strToReturn .= $strName[$intIndex];
 754: 
 755:             if (is_numeric(QString::FirstCharacter($strToReturn)))
 756:                 $strToReturn = '_' . $strToReturn;
 757:             return $strToReturn;
 758:         }
 759: 
 760:         /**
 761:          * Returns the control label name as used in the ModelConnector corresponding to this column or table.
 762:          *
 763:          * @param QSqlColumn|QReverseReference|QManyToManyReference $objColumn
 764:          *
 765:          * @return string
 766:          */
 767:         public static function ModelConnectorControlName ($objColumn) {
 768:             if (($o = $objColumn->Options) && isset ($o['Name'])) { // Did developer default?
 769:                 return $o['Name'];
 770:             }
 771:             return QConvertNotation::WordsFromCamelCase(QCodeGen::ModelConnectorPropertyName($objColumn));
 772:         }
 773: 
 774:         /**
 775:          * The property name used in the ModelConnector for the given column, virtual column or table
 776:          *
 777:          * @param QSqlColumn|QReverseReference|QManyToManyReference $objColumn
 778:          *
 779:          * @return string
 780:          * @throws Exception
 781:          */
 782:         public static function ModelConnectorPropertyName ($objColumn) {
 783:             if ($objColumn instanceof QSqlColumn) {
 784:                 if ($objColumn->Reference) {
 785:                     return $objColumn->Reference->PropertyName;
 786:                 } else {
 787:                     return $objColumn->PropertyName;
 788:                 }
 789:             }
 790:             elseif ($objColumn instanceof QReverseReference) {
 791:                 if ($objColumn->Unique) {
 792:                     return ($objColumn->ObjectDescription);
 793:                 }
 794:                 else {
 795:                     return ($objColumn->ObjectDescriptionPlural);
 796:                 }
 797:             }
 798:             elseif ($objColumn instanceof QManyToManyReference) {
 799:                 return $objColumn->ObjectDescriptionPlural;
 800:             }
 801:             else {
 802:                 throw new Exception ('Unknown column type.');
 803:             }
 804:         }
 805: 
 806:         /**
 807:          * Return a variable name corresponding to the given column, including virtual columns like
 808:          * QReverseReference and QManyToMany references.
 809:          * @param QSqlColumn|QReverseReference|QManyToManyReference $objColumn
 810:          * @return string
 811:          */
 812:         public function ModelConnectorVariableName($objColumn) {
 813:             $strPropName = static::ModelConnectorPropertyName($objColumn);
 814:             $objControlHelper = $this->GetControlCodeGenerator($objColumn);
 815:             return $objControlHelper->VarName ($strPropName);
 816:         }
 817: 
 818:         /**
 819:          * Returns a variable name for the "label" version of a control, which would be the read-only version
 820:          * of viewing the data in the column.
 821:          * @param QSqlColumn|QReverseReference|QManyToManyReference $objColumn
 822:          * @return string
 823:          */
 824:         public function ModelConnectorLabelVariableName($objColumn) {
 825:             $strPropName = static::ModelConnectorPropertyName($objColumn);
 826:             return QLabel_CodeGenerator::Instance()->VarName($strPropName);
 827:         }
 828: 
 829:         /**
 830:          * Returns the class for the control that will be created to edit the given column,
 831:          * including the 'virtual' columns of reverse references (many to one) and many-to-many references.
 832:          *
 833:          * @param QSqlColumn|QReverseReference|QManyToManyReference $objColumn
 834:          *
 835:          * @return string Class name of control which can handle this column's data
 836:          * @throws Exception
 837:          */
 838:         protected function ModelConnectorControlClass($objColumn) {
 839: 
 840:             // Is the class specified by the developer?
 841:             if ($o = $objColumn->Options) {
 842:                 if (isset ($o['FormGen']) && $o['FormGen'] == QFormGen::LabelOnly) {
 843:                     return 'QLabel';
 844:                 }
 845:                 if (isset($o['ControlClass'])) {
 846:                     return $o['ControlClass'];
 847:                 }
 848:             }
 849: 
 850:             // otherwise, return the default class based on the column
 851:             if ($objColumn instanceof QSqlColumn) {
 852:                 if ($objColumn->Identity)
 853:                     return 'QLabel';
 854: 
 855:                 if ($objColumn->Timestamp)
 856:                     return 'QLabel';
 857: 
 858:                 if ($objColumn->Reference)
 859:                     return 'QListBox';
 860: 
 861:                 switch ($objColumn->VariableType) {
 862:                     case QType::Boolean:
 863:                         return 'QCheckBox';
 864:                     case QType::DateTime:
 865:                         return 'QDateTimePicker';
 866:                     case QType::Integer:
 867:                         return 'QIntegerTextBox';
 868:                     case QType::Float:
 869:                         return 'QFloatTextBox';
 870:                     default:
 871:                         return 'QTextBox';
 872:                 }
 873:             }
 874:             elseif ($objColumn instanceof QReverseReference) {
 875:                 if ($objColumn->Unique) {
 876:                     return 'QListBox';
 877:                 } else {
 878:                     return 'QCheckBoxList'; // for multi-selection
 879:                 }
 880:             }
 881:             elseif ($objColumn instanceof QManyToManyReference) {
 882:                 return 'QCheckBoxList'; // for multi-selection
 883:             }
 884:             throw new Exception('Unknown column type.');
 885:         }
 886: 
 887: 
 888:         public function DataListControlClass (QSqlTable $objTable) {
 889:             // Is the class specified by the developer?
 890:             if ($o = $objTable->Options) {
 891:                 if (isset($o['ControlClass'])) {
 892:                     return $o['ControlClass'];
 893:                 }
 894:             }
 895: 
 896:             // Otherwise, return a default
 897:             return 'QDataGrid';
 898:         }
 899: 
 900:         /**
 901:          * Returns the control label name as used in the data list panel corresponding to this column.
 902:          *
 903:          * @param QSqlTable $objTable
 904:          *
 905:          * @return string
 906:          */
 907:         public static function DataListControlName (QSqlTable $objTable) {
 908:             if (($o = $objTable->Options) && isset ($o['Name'])) { // Did developer default?
 909:                 return $o['Name'];
 910:             }
 911:             return QConvertNotation::WordsFromCamelCase($objTable->ClassNamePlural);
 912:         }
 913: 
 914:         /**
 915:          * Returns the name of an item in the data list as will be displayed in the edit panel.
 916:          *
 917:          * @param QSqlTable $objTable
 918:          *
 919:          * @return string
 920:          */
 921:         public static function DataListItemName (QSqlTable $objTable) {
 922:             if (($o = $objTable->Options) && isset ($o['ItemName'])) { // Did developer override?
 923:                 return $o['ItemName'];
 924:             }
 925:             return QConvertNotation::WordsFromCamelCase($objTable->ClassName);
 926:         }
 927: 
 928:         public function DataListVarName (QSqlTable $objTable) {
 929:             $strPropName = self::DataListPropertyNamePlural($objTable);
 930:             $objControlHelper = $this->GetDataListCodeGenerator($objTable);
 931:             return $objControlHelper->VarName($strPropName);
 932:         }
 933: 
 934:         public static function DataListPropertyName (QSqlTable $objTable) {
 935:             return $objTable->ClassName;
 936:         }
 937: 
 938:         public static function DataListPropertyNamePlural (QSqlTable $objTable) {
 939:             return $objTable->ClassNamePlural;
 940:         }
 941: 
 942: 
 943:         /**
 944:          * Returns the class for the control that will be created to edit the given column,
 945:          * including the 'virtual' columns of reverse references (many to one) and many-to-many references.
 946:          *
 947:          * @param QSqlColumn|QReverseReference|QManyToManyReference $objColumn
 948:          *
 949:          * @return AbstractControl_CodeGenerator helper object
 950:          * @throws Exception
 951:          */
 952:         public function GetControlCodeGenerator($objColumn) {
 953:             $strControlClass = $this->ModelConnectorControlClass($objColumn);
 954: 
 955:             if (method_exists($strControlClass, 'GetCodeGenerator')) {
 956:                 return call_user_func($strControlClass.'::GetCodeGenerator');
 957:             }
 958: 
 959:             switch ($strControlClass) {
 960:                 case 'QLabel': return QLabel_CodeGenerator::Instance();
 961:                 case 'QListBox': return new QListBox_CodeGenerator();
 962:                 case 'QCheckBox': return new QCheckBox_CodeGenerator();
 963:                 case 'QDateTimePicker': return new QDateTimePicker_CodeGenerator();
 964:                 case 'QTextBox': return new QTextBox_CodeGenerator();
 965:                 case 'QIntegerTextBox': return new QIntegerTextBox_CodeGenerator();
 966:                 case 'QFloatTextBox': return new QFloatTextBox_CodeGenerator();
 967:                 case 'QCheckBoxList': return new QCheckBoxList_CodeGenerator();
 968:                 default: break;
 969:             }
 970: 
 971:             $strOrigControlClass = $strControlClass;
 972:             $strControlCodeGeneratorClass = $strControlClass .'_CodeGenerator';
 973:             while (!class_exists($strControlCodeGeneratorClass)) {
 974:                 $strControlClass = get_parent_class($strControlClass);
 975:                 if ($strControlClass === 'QControl') {
 976:                     throw new QCallerException("Cannot find an appropriate subclass of AbstractControl_CodeGenerator for ".$strOrigControlClass);
 977:                 }
 978:                 $strControlCodeGeneratorClass = $strControlClass .'_CodeGenerator';
 979:             }
 980:             return new $strControlCodeGeneratorClass($strOrigControlClass);
 981:         }
 982: 
 983:         public function GetDataListCodeGenerator($objTable) {
 984:             $strControlClass = $this->DataListControlClass($objTable);
 985: 
 986:             if (method_exists($strControlClass, 'GetCodeGenerator')) {
 987:                 return call_user_func($strControlClass.'::GetCodeGenerator');
 988:             }
 989: 
 990:             return new QDataGrid_CodeGenerator();
 991:         }
 992: 
 993: 
 994:         protected function CalculateObjectMemberVariable($strTableName, $strColumnName, $strReferencedTableName) {
 995:             return sprintf('%s%s%s%s',
 996:                 QConvertNotation::PrefixFromType(QType::Object),
 997:                 $this->strAssociatedObjectPrefix,
 998:                 $this->CalculateObjectDescription($strTableName, $strColumnName, $strReferencedTableName, false),
 999:                 $this->strAssociatedObjectSuffix);
1000:         }
1001: 
1002:         protected function CalculateObjectPropertyName($strTableName, $strColumnName, $strReferencedTableName) {
1003:             return sprintf('%s%s%s',
1004:                 $this->strAssociatedObjectPrefix,
1005:                 $this->CalculateObjectDescription($strTableName, $strColumnName, $strReferencedTableName, false),
1006:                 $this->strAssociatedObjectSuffix);
1007:         }
1008: 
1009:         // TODO: These functions need to be documented heavily with information from "lexical analysis on fk names.txt"
1010:         protected function CalculateObjectDescription($strTableName, $strColumnName, $strReferencedTableName, $blnPluralize) {
1011:             // Strip Prefixes (if applicable)
1012:             $strTableName = $this->StripPrefixFromTable($strTableName);
1013:             $strReferencedTableName = $this->StripPrefixFromTable($strReferencedTableName);
1014: 
1015:             // Starting Point
1016:             $strToReturn = QConvertNotation::CamelCaseFromUnderscore($strTableName);
1017: 
1018:             if ($blnPluralize)
1019:                 $strToReturn = $this->Pluralize($strToReturn);
1020: 
1021:             if ($strTableName == $strReferencedTableName) {
1022:                 // Self-referencing Reference to Describe
1023: 
1024:                 // If Column Name is only the name of the referenced table, or the name of the referenced table with "_id",
1025:                 // then the object description is simply based off the table name.
1026:                 if (($strColumnName == $strReferencedTableName) ||
1027:                     ($strColumnName == $strReferencedTableName . '_id'))
1028:                     return sprintf('Child%s', $strToReturn);
1029: 
1030:                 // Rip out trailing "_id" if applicable
1031:                 $intLength = strlen($strColumnName);
1032:                 if (($intLength > 3) && (substr($strColumnName, $intLength - 3) == "_id"))
1033:                     $strColumnName = substr($strColumnName, 0, $intLength - 3);
1034: 
1035:                 // Rip out the referenced table name from the column name
1036:                 $strColumnName = str_replace($strReferencedTableName, "", $strColumnName);
1037: 
1038:                 // Change any double "_" to single "_"
1039:                 $strColumnName = str_replace("__", "_", $strColumnName);
1040:                 $strColumnName = str_replace("__", "_", $strColumnName);
1041: 
1042:                 $strColumnName = QConvertNotation::CamelCaseFromUnderscore($strColumnName);
1043: 
1044:                 // Special case for Parent/Child
1045:                 if ($strColumnName == 'Parent')
1046:                     return sprintf('Child%s', $strToReturn);
1047: 
1048:                 return sprintf("%sAs%s",
1049:                     $strToReturn, $strColumnName);
1050: 
1051:             } else {
1052:                 // If Column Name is only the name of the referenced table, or the name of the referenced table with "_id",
1053:                 // then the object description is simply based off the table name.
1054:                 if (($strColumnName == $strReferencedTableName) ||
1055:                     ($strColumnName == $strReferencedTableName . '_id'))
1056:                     return $strToReturn;
1057: 
1058:                 // Rip out trailing "_id" if applicable
1059:                 $intLength = strlen($strColumnName);
1060:                 if (($intLength > 3) && (substr($strColumnName, $intLength - 3) == "_id"))
1061:                     $strColumnName = substr($strColumnName, 0, $intLength - 3);
1062: 
1063:                 // Rip out the referenced table name from the column name
1064:                 $strColumnName = str_replace($strReferencedTableName, "", $strColumnName);
1065: 
1066:                 // Change any double "_" to single "_"
1067:                 $strColumnName = str_replace("__", "_", $strColumnName);
1068:                 $strColumnName = str_replace("__", "_", $strColumnName);
1069: 
1070:                 return sprintf("%sAs%s",
1071:                     $strToReturn,
1072:                     QConvertNotation::CamelCaseFromUnderscore($strColumnName));
1073:             }
1074:         }
1075: 
1076:         // this is called for ReverseReference Object Descriptions for association tables (many-to-many)
1077:         protected function CalculateObjectDescriptionForAssociation($strAssociationTableName, $strTableName, $strReferencedTableName, $blnPluralize) {
1078:             // Strip Prefixes (if applicable)
1079:             $strTableName = $this->StripPrefixFromTable($strTableName);
1080:             $strAssociationTableName = $this->StripPrefixFromTable($strAssociationTableName);
1081:             $strReferencedTableName = $this->StripPrefixFromTable($strReferencedTableName);
1082: 
1083:             // Starting Point
1084:             $strToReturn = QConvertNotation::CamelCaseFromUnderscore($strReferencedTableName);
1085: 
1086:             if ($blnPluralize)
1087:                 $strToReturn = $this->Pluralize($strToReturn);
1088: 
1089:             // Let's start with strAssociationTableName
1090: 
1091:             // Rip out trailing "_assn" if applicable
1092:             $strAssociationTableName = str_replace($this->strAssociationTableSuffix, '', $strAssociationTableName);
1093: 
1094:             // remove instances of the table names in the association table name
1095:             $strTableName2 = str_replace('_', '', $strTableName); // remove underscores if they are there
1096:             $strReferencedTableName2 = str_replace('_', '', $strReferencedTableName); // remove underscores if they are there
1097: 
1098:             if (beginsWith ($strAssociationTableName, $strTableName . '_')) {
1099:                 $strAssociationTableName = trimOffFront ($strTableName . '_', $strAssociationTableName);
1100:             } elseif (beginsWith ($strAssociationTableName, $strTableName2 . '_')) {
1101:                 $strAssociationTableName = trimOffFront ($strTableName2 . '_', $strAssociationTableName);
1102:             } elseif (beginsWith ($strAssociationTableName, $strReferencedTableName . '_')) {
1103:                 $strAssociationTableName = trimOffFront ($strReferencedTableName . '_', $strAssociationTableName);
1104:             } elseif (beginsWith ($strAssociationTableName, $strReferencedTableName2 . '_')) {
1105:                 $strAssociationTableName = trimOffFront ($strReferencedTableName2 . '_', $strAssociationTableName);
1106:             } elseif ($strAssociationTableName == $strTableName ||
1107:                     $strAssociationTableName == $strTableName2 ||
1108:                     $strAssociationTableName == $strReferencedTableName ||
1109:                     $strAssociationTableName == $strReferencedTableName2) {
1110:                 $strAssociationTableName = "";
1111:             }
1112: 
1113:             if (endsWith ($strAssociationTableName,  '_' . $strTableName)) {
1114:                 $strAssociationTableName = trimOffEnd ('_' . $strTableName, $strAssociationTableName);
1115:             } elseif (endsWith ($strAssociationTableName, '_' . $strTableName2)) {
1116:                 $strAssociationTableName = trimOffEnd ('_' . $strTableName2, $strAssociationTableName);
1117:             } elseif (endsWith ($strAssociationTableName,  '_' . $strReferencedTableName)) {
1118:                 $strAssociationTableName = trimOffEnd ('_' . $strReferencedTableName, $strAssociationTableName);
1119:             } elseif (endsWith ($strAssociationTableName, '_' . $strReferencedTableName2)) {
1120:                 $strAssociationTableName = trimOffEnd ('_' . $strReferencedTableName2, $strAssociationTableName);
1121:             } elseif ($strAssociationTableName == $strTableName ||
1122:                     $strAssociationTableName == $strTableName2 ||
1123:                     $strAssociationTableName == $strReferencedTableName ||
1124:                     $strAssociationTableName == $strReferencedTableName2) {
1125:                 $strAssociationTableName = "";
1126:             }
1127: 
1128:             // Change any double "__" to single "_"
1129:             $strAssociationTableName = str_replace("__", "_", $strAssociationTableName);
1130:             $strAssociationTableName = str_replace("__", "_", $strAssociationTableName);
1131:             $strAssociationTableName = str_replace("__", "_", $strAssociationTableName);
1132: 
1133:             // If we have nothing left or just a single "_" in AssociationTableName, return "Starting Point"
1134:             if (($strAssociationTableName == "_") || ($strAssociationTableName == ""))
1135:                 return sprintf("%s%s%s",
1136:                     $this->strAssociatedObjectPrefix,
1137:                     $strToReturn,
1138:                     $this->strAssociatedObjectSuffix);
1139: 
1140:             // Otherwise, add "As" and the predicate
1141:             return sprintf("%s%sAs%s%s",
1142:                 $this->strAssociatedObjectPrefix,
1143:                 $strToReturn,
1144:                 QConvertNotation::CamelCaseFromUnderscore($strAssociationTableName),
1145:                 $this->strAssociatedObjectSuffix);
1146:         }
1147: 
1148:         // This is called by AnalyzeAssociationTable to calculate the GraphPrefixArray for a self-referencing association table (e.g. directed graph)
1149:         protected function CalculateGraphPrefixArray($objForeignKeyArray) {
1150:             // Analyze Column Names to determine GraphPrefixArray
1151:             if ((strpos(strtolower($objForeignKeyArray[0]->ColumnNameArray[0]), 'parent') !== false) ||
1152:                 (strpos(strtolower($objForeignKeyArray[1]->ColumnNameArray[0]), 'child') !== false)) {
1153:                 $strGraphPrefixArray[0] = '';
1154:                 $strGraphPrefixArray[1] = 'Parent';
1155:             } else if ((strpos(strtolower($objForeignKeyArray[0]->ColumnNameArray[0]), 'child') !== false) ||
1156:                         (strpos(strtolower($objForeignKeyArray[1]->ColumnNameArray[0]), 'parent') !== false)) {
1157:                 $strGraphPrefixArray[0] = 'Parent';
1158:                 $strGraphPrefixArray[1] = '';
1159:             } else {
1160:                 // Use Default Prefixing for Graphs
1161:                 $strGraphPrefixArray[0] = 'Parent';
1162:                 $strGraphPrefixArray[1] = '';
1163:             }
1164: 
1165:             return $strGraphPrefixArray;
1166:         }
1167: 
1168:         /**
1169:          * Returns the variable type corresponding to the database column type
1170:          * @param string $strDbType
1171:          * @return string
1172:          * @throws Exception
1173:          */
1174:         protected function VariableTypeFromDbType($strDbType) {
1175:             switch ($strDbType) {
1176:                 case QDatabaseFieldType::Bit:
1177:                     return QType::Boolean;
1178:                 case QDatabaseFieldType::Blob:
1179:                     return QType::String;
1180:                 case QDatabaseFieldType::Char:
1181:                     return QType::String;
1182:                 case QDatabaseFieldType::Date:
1183:                     return QType::DateTime;
1184:                 case QDatabaseFieldType::DateTime:
1185:                     return QType::DateTime;
1186:                 case QDatabaseFieldType::Float:
1187:                     return QType::Float;
1188:                 case QDatabaseFieldType::Integer:
1189:                     return QType::Integer;
1190:                 case QDatabaseFieldType::Time:
1191:                     return QType::DateTime;
1192:                 case QDatabaseFieldType::VarChar:
1193:                     return QType::String;
1194:                 case QDatabaseFieldType::Json:
1195:                     return QType::String;
1196:                 default:
1197:                     throw new Exception("Invalid Db Type to Convert: $strDbType");
1198:             }
1199:         }
1200: 
1201:         /**
1202:          * Return the plural of the given name. Override this and return the plural version of particular names
1203:          * if this generic version isn't working for you.
1204:          *
1205:          * @param string $strName
1206:          * @return string
1207:          */
1208:         protected function Pluralize($strName) {
1209:             // Special Rules go Here
1210:             switch (true) {
1211:                 case (strtolower($strName) == 'play'):
1212:                     return $strName . 's';
1213:             }
1214: 
1215:             $intLength = strlen($strName);
1216:             if (substr($strName, $intLength - 1) == "y")
1217:                 return substr($strName, 0, $intLength - 1) . "ies";
1218:             if (substr($strName, $intLength - 1) == "s")
1219:                 return $strName . "es";
1220:             if (substr($strName, $intLength - 1) == "x")
1221:                 return $strName . "es";
1222:             if (substr($strName, $intLength - 1) == "z")
1223:                 return $strName . "zes";
1224:             if (substr($strName, $intLength - 2) == "sh")
1225:                 return $strName . "es";
1226:             if (substr($strName, $intLength - 2) == "ch")
1227:                 return $strName . "es";
1228: 
1229:             return $strName . "s";
1230:         }
1231: 
1232:         public function ReportError ($strError) {
1233:             $this->strErrors .= $strError . "\r\n";
1234:         }
1235: 
1236:         ////////////////////
1237:         // Public Overriders
1238:         ////////////////////
1239: 
1240:         /**
1241:          * Override method to perform a property "Get"
1242:          * This will get the value of $strName
1243:          *
1244:          * @param string $strName
1245:          *
1246:          * @throws Exception|QCallerException
1247:          * @return mixed
1248:          */
1249:         public function __get($strName) {
1250:             switch ($strName) {
1251:                 case 'Errors':
1252:                     return $this->strErrors;
1253:                 case 'Warnings':
1254:                     return $this->strWarnings;
1255:                 default:
1256:                     try {
1257:                         return parent::__get($strName);
1258:                     } catch (QCallerException $objExc) {
1259:                         $objExc->IncrementOffset();
1260:                         throw $objExc;
1261:                     }
1262:             }
1263:         }
1264: 
1265:         /**
1266:          * PHP magic method to set class properties
1267:          * @param string $strName
1268:          * @param string $mixValue
1269:          *
1270:          * @return mixed|void
1271:          */
1272:         public function __set($strName, $mixValue) {
1273:             try {
1274:                 switch($strName) {
1275:                     case 'Errors':
1276:                         return ($this->strErrors = QType::Cast($mixValue, QType::String));
1277:                     case 'Warnings':
1278:                         return ($this->strWarnings = QType::Cast($mixValue, QType::String));
1279:                     default:
1280:                         return parent::__set($strName, $mixValue);
1281:                 }
1282:             } catch (QCallerException $objExc) {
1283:                 $objExc->IncrementOffset();
1284:             }
1285:         }
1286:     }
API documentation generated by ApiGen