From 58eb50f0ad427b3d747d290059490436f6b1473b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Sun, 28 Sep 2014 02:37:53 +0200 Subject: [PATCH] Added custom Blogposts for ProblemEulerBefunge --- .../blogpost_ProjectEulerBefunge_style.css | 76 ++++++++ www/css/styles.css | 129 +++++++++++++ www/data/blog/Befunge/.gitignore | 1 + www/data/blog/{Befunge_2 => Befunge}/p015.gif | Bin www/index-test.php | 7 +- www/protected/components/MSController.php | 5 + www/protected/components/MsHelper.php | 50 +++++ www/protected/config/main.php | 2 + .../controllers/BlogpostController.php | 141 ++++++++++---- .../controllers/EulerProblemController.php | 169 +++++++++++++++++ .../controllers/MsmainController.php | 2 +- www/protected/models/BlogPost.php | 12 +- www/protected/models/EulerProblem.php | 177 ++++++++++++++++++ www/protected/models/HighscoreEntries.php | 1 - www/protected/models/HighscoreGames.php | 2 - www/protected/views/blogpost/_form.php | 2 + www/protected/views/blogpost/_search.php | 2 + www/protected/views/blogpost/_view.php | 5 + .../blogpost/view_ProjectEulerBefunge.php | 168 +++++++++++++++++ www/protected/views/eulerProblem/_form.php | 57 ++++++ www/protected/views/eulerProblem/_search.php | 41 ++++ www/protected/views/eulerProblem/_view.php | 55 ++++++ www/protected/views/eulerProblem/admin.php | 64 +++++++ www/protected/views/eulerProblem/create.php | 20 ++ www/protected/views/eulerProblem/index.php | 35 ++++ www/protected/views/eulerProblem/update.php | 23 +++ www/protected/views/eulerProblem/view.php | 38 ++++ www/protected/views/layouts/main.php | 10 +- www/protected/views/msmain/admin.php | 54 +++++- www/protected/views/programs/index.php | 9 + www/protected/views/programs/view.php | 7 +- 31 files changed, 1314 insertions(+), 50 deletions(-) create mode 100644 www/css/blogpost_ProjectEulerBefunge_style.css create mode 100644 www/data/blog/Befunge/.gitignore rename www/data/blog/{Befunge_2 => Befunge}/p015.gif (100%) create mode 100644 www/protected/controllers/EulerProblemController.php create mode 100644 www/protected/models/EulerProblem.php create mode 100644 www/protected/views/blogpost/view_ProjectEulerBefunge.php create mode 100644 www/protected/views/eulerProblem/_form.php create mode 100644 www/protected/views/eulerProblem/_search.php create mode 100644 www/protected/views/eulerProblem/_view.php create mode 100644 www/protected/views/eulerProblem/admin.php create mode 100644 www/protected/views/eulerProblem/create.php create mode 100644 www/protected/views/eulerProblem/index.php create mode 100644 www/protected/views/eulerProblem/update.php create mode 100644 www/protected/views/eulerProblem/view.php diff --git a/www/css/blogpost_ProjectEulerBefunge_style.css b/www/css/blogpost_ProjectEulerBefunge_style.css new file mode 100644 index 0000000..83c8b75 --- /dev/null +++ b/www/css/blogpost_ProjectEulerBefunge_style.css @@ -0,0 +1,76 @@ +.PEB_tableProblems { + width: 100%; +} + +.PEB_tablerowProblems { + +} + +.PEB_tablecellProblems { + +} + +.PEB_TC_Value:not(:hover) { + color: transparent; + + -o-transition:.5s; + -ms-transition:.5s; + -moz-transition:.5s; + -webkit-transition:.5s; + transition:.5s; +} + +.PEB_TC_Value:hover { + color: black; + + -o-transition:.5s; + -ms-transition:.5s; + -moz-transition:.5s; + -webkit-transition:.5s; + transition:.5s; +} + +.PEB_TC_Time { + border-radius: 5px; + + display: inline-block; + padding: 1px 6px; +} + +.PEB_TC_Timelevel_0 { background-color: #0A0 !important; } + +.PEB_TC_Timelevel_1 { background-color: #84FF0A !important; } + +.PEB_TC_Timelevel_2 { background-color: #FF0 !important; } + +.PEB_TC_Timelevel_3 { background-color: #F60 !important; } + +.PEB_TC_Timelevel_4 { background-color: #F11 !important; } + +.PEB_TC_Size_93 { + display: inline-flex; + float: right; + + + border-radius: 5px; + background-color: #0A0; + + display: inline-block; + padding: 1px 6px; +} + +.PEB_TC_Size_98 { + display: inline-flex; + float: right; + + + border-radius: 5px; + background-color: #FF0; + + display: inline-block; + padding: 1px 6px; +} + +.PEB_TC_Title a { + color: #2C3E50; +} \ No newline at end of file diff --git a/www/css/styles.css b/www/css/styles.css index fc6b002..abd1646 100644 --- a/www/css/styles.css +++ b/www/css/styles.css @@ -768,3 +768,132 @@ ul.nav li.dropdown-append:hover > ul.dropdown-menu { font-size: small; } +/* Pagination +-------------------------------------------------- */ + +.pagination { + margin:20px 0; +} + +.pagination ul { + display:inline-block; + *display:inline; + *zoom:1; + margin-left:0; + margin-bottom:0; + -webkit-border-radius:4px; + -moz-border-radius:4px; + border-radius:4px; + -webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05); + -moz-box-shadow:0 1px 2px rgba(0,0,0,0.05); + box-shadow:0 1px 2px rgba(0,0,0,0.05); +} + +.pagination ul>li { + display:inline; +} + +.pagination ul>li>a,.pagination ul>li>span{ + float:left; + padding:4px 12px; + line-height:20px; + text-decoration:none; + background-color:#fff; + border:1px solid #ddd; + border-left-width:0; + + color: #888; +} + +.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{ + background-color:#f5f5f5; +} + +.pagination ul>.active>a,.pagination ul>.active>span{ + color:#999; + cursor:default; +} + +.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{ + color:#999; + background-color:transparent; + cursor:default; +} + +.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{ + border-left-width:1px; + -webkit-border-top-left-radius:4px; + -moz-border-radius-topleft:4px; + border-top-left-radius:4px; + -webkit-border-bottom-left-radius:4px; + -moz-border-radius-bottomleft:4px; + border-bottom-left-radius:4px; +} + +.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{ + -webkit-border-top-right-radius:4px; + -moz-border-radius-topright:4px; + border-top-right-radius:4px; + -webkit-border-bottom-right-radius:4px; + -moz-border-radius-bottomright:4px; + border-bottom-right-radius:4px; +} + +.pagination-centered { + text-align:center; +} + +.pagination-right{ + text-align:right; +} + +.pagination-large ul>li>a, .pagination-large ul>li>span { + padding:11px 19px; + font-size:17.5px; +} + +.pagination-large ul>li:first-child>a, .pagination-large ul>li:first-child>span { + -webkit-border-top-left-radius:6px; + -moz-border-radius-topleft:6px; + border-top-left-radius:6px; + -webkit-border-bottom-left-radius:6px; + -moz-border-radius-bottomleft:6px; + border-bottom-left-radius:6px; +} + +.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span { + -webkit-border-top-right-radius:6px; + -moz-border-radius-topright:6px; + border-top-right-radius:6px; + -webkit-border-bottom-right-radius:6px; + -moz-border-radius-bottomright:6px; + border-bottom-right-radius:6px; +} + +.pagination-mini ul>li:first-child>a, .pagination-small ul>li:first-child>a, .pagination-mini ul>li:first-child>span, .pagination-small ul>li:first-child>span { + -webkit-border-top-left-radius:3px; + -moz-border-radius-topleft:3px; + border-top-left-radius:3px; + -webkit-border-bottom-left-radius:3px; + -moz-border-radius-bottomleft:3px; + border-bottom-left-radius:3px; +} + +.pagination-mini ul>li:last-child>a, .pagination-small ul>li:last-child>a, .pagination-mini ul>li:last-child>span, .pagination-small ul>li:last-child>span { + -webkit-border-top-right-radius:3px; + -moz-border-radius-topright:3px; + border-top-right-radius:3px; + -webkit-border-bottom-right-radius:3px; + -moz-border-radius-bottomright:3px; + border-bottom-right-radius:3px; +} + +.pagination-small ul>li>a, .pagination-small ul>li>span{ + padding:2px 10px; + font-size:11.9px; +} + +.pagination-mini ul>li>a,.pagination-mini ul>li>span{ + padding:0 6px; + font-size:10.5px; +} \ No newline at end of file diff --git a/www/data/blog/Befunge/.gitignore b/www/data/blog/Befunge/.gitignore new file mode 100644 index 0000000..b7fbb07 --- /dev/null +++ b/www/data/blog/Befunge/.gitignore @@ -0,0 +1 @@ +*.b93 \ No newline at end of file diff --git a/www/data/blog/Befunge_2/p015.gif b/www/data/blog/Befunge/p015.gif similarity index 100% rename from www/data/blog/Befunge_2/p015.gif rename to www/data/blog/Befunge/p015.gif diff --git a/www/index-test.php b/www/index-test.php index df9b070..99e6f69 100644 --- a/www/index-test.php +++ b/www/index-test.php @@ -55,9 +55,4 @@ defined('YII_DEBUG') or define('YII_DEBUG',true); defined('YII_CUSTOM_ENV') or define('YII_CUSTOM_ENV', 'prod'); require_once($yii); -Yii::createWebApplication($config)->run(); - - -// TODO-MS Add Blog -// TODO-MS Add Search (Blog + progs + log) jew auch metadata / desc ... -// TODO-MS Add Prog Display +Yii::createWebApplication($config)->run(); \ No newline at end of file diff --git a/www/protected/components/MSController.php b/www/protected/components/MSController.php index 9fd723e..88ce418 100644 --- a/www/protected/components/MSController.php +++ b/www/protected/components/MSController.php @@ -12,6 +12,11 @@ class MSController extends CController public $selectedNav = ''; public $js_scripts = array(); + public $css_files = + [ + "/css/styles.css", + "/css/prism.css", + ]; public $title = null; diff --git a/www/protected/components/MsHelper.php b/www/protected/components/MsHelper.php index 86c866e..6376aee 100644 --- a/www/protected/components/MsHelper.php +++ b/www/protected/components/MsHelper.php @@ -54,4 +54,54 @@ class MsHelper { } rmdir($dirPath); } + + public static function formatMilliseconds($millis) + { + if ($millis < 1000) + { + return $millis . 'ms'; + } + else if ($millis < 10 * 1000) + { + return number_format($millis / (1000), 2) . 's'; + } + else if ($millis < 60 * 1000) + { + return floor($millis / (1000)) . 's'; + } + else if ($millis < 10 * 60 * 1000) + { + return floor($millis / (60 * 1000)) . 'min ' . floor(($millis % (60 * 1000)) / 1000) . 's'; + } + else if ($millis < 60 * 60 * 1000) + { + return floor($millis / (60 * 1000)) . 'min'; + } + else if ($millis < 10 * 60 * 60 * 1000) + { + return number_format($millis / (60 * 60 * 1000), 2) . ' hours'; + } + else + { + return floor($millis / (60 * 60 * 1000)) . ' hours'; + } + } + + /** + * Appends/Prepends $before/$after to every line in $input + * + * @param $input + * @param $before + * @param $after + * @return mixed + */ + public function encloseLines($input, $before, $after) + { + $array = preg_split("/\r\n|\n|\r/", $input); + + for($i = 0; $i < count($array); $i++) + $array[$i] = $before . $array[$i] . $after; + + return implode(PHP_EOL, $array); + } } \ No newline at end of file diff --git a/www/protected/config/main.php b/www/protected/config/main.php index 70a4a34..da8aa4a 100644 --- a/www/protected/config/main.php +++ b/www/protected/config/main.php @@ -100,6 +100,8 @@ return ArrayX::merge( 'blog/' => 'blogPost/view/id/', 'blog//' => 'blogPost/view/id/', + 'eulerProblem/' => 'eulerProblem/index', + 'Highscores/list.php' => 'Highscores/list', // Compatibility 'Highscores/insert.php' => 'Highscores/insert', // Compatibility 'Highscores/update.php' => 'Highscores/update', // Compatibility diff --git a/www/protected/controllers/BlogpostController.php b/www/protected/controllers/BlogpostController.php index 6ca3cd3..9985dd6 100644 --- a/www/protected/controllers/BlogpostController.php +++ b/www/protected/controllers/BlogpostController.php @@ -22,19 +22,16 @@ class BlogPostController extends MSController public function accessRules() { return array( - array('allow', // allow all users to perform 'index' and 'view' actions + array('allow', 'actions'=>array('index','view', 'ajaxMarkdownPreview'), 'users'=>array('*'), ), - array('allow', // allow authenticated user to perform 'create' and 'update' actions + array('allow', 'actions'=>array('create','update','admin','delete'), 'users'=>array('@'), ), -// array('allow', // allow admin user to perform 'admin' and 'delete' actions -// 'actions'=>array(), -// 'users'=>array('admin'), -// ), - array('deny', // deny everythign else to all users + + array('deny', 'users'=>array('*'), ), ); @@ -45,17 +42,30 @@ class BlogPostController extends MSController * @param integer $id the ID of the model to be displayed * @throws CHttpException if Enabled is false */ - public function actionView($id) + public function actionView($id) //TODO-MS add BFJoust to Blog { $model = $this->loadModel($id); if (! $model->Enabled && Yii::app()->user->name != 'admin') throw new CHttpException(403, 'This Blogpost is locked'); - $this->render('view', - [ - 'model' => $model, - ]); + if ($model->isSpecialBlogPost()) + { + $controllerMethod = 'viewBlogpost' . $model->ControllerID; + if(is_callable([$this, $controllerMethod])) + $this->$controllerMethod($model); + else + throw new CHttpException(500, 'Unknown ControllerID: ' . $controllerMethod); + } + else + { + $this->render('view', + [ + 'model' => $model, + ]); + } + + } /** @@ -71,16 +81,19 @@ class BlogPostController extends MSController // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); - if (isset($_POST['BlogPost'])) { + if (isset($_POST['BlogPost'])) + { $model->attributes=$_POST['BlogPost']; - if ($model->save()) { + if ($model->save()) + { $this->redirect(array('view','id'=>$model->ID)); } } - $this->render('create',array( - 'model'=>$model, - )); + $this->render('create', + [ + 'model'=>$model, + ]); } /** @@ -97,16 +110,19 @@ class BlogPostController extends MSController // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); - if (isset($_POST['BlogPost'])) { + if (isset($_POST['BlogPost'])) + { $model->attributes=$_POST['BlogPost']; - if ($model->save()) { - $this->redirect(array('view','id'=>$model->ID)); + if ($model->save()) + { + $this->redirect(['view','id'=>$model->ID]); } } - $this->render('update',array( - 'model'=>$model, - )); + $this->render('update', + [ + 'model'=>$model, + ]); } /** @@ -122,7 +138,8 @@ class BlogPostController extends MSController $this->loadModel($id)->delete(); // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser - if (!isset($_GET['ajax'])) { + if (!isset($_GET['ajax'])) + { $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin')); } } @@ -150,14 +167,18 @@ class BlogPostController extends MSController ); } - public function actionAjaxMarkdownPreview() { - if(Yii::app()->request->isAjaxRequest){ + public function actionAjaxMarkdownPreview() + { + if(Yii::app()->request->isAjaxRequest) + { $this->renderPartial('_ajaxMarkdownPreview', [ 'Content' => $_POST['Content'], ], false, true); - } else { + } + else + { throw new CHttpException(400,'Invalid request. This is a Ajax only action.'); } } @@ -171,13 +192,15 @@ class BlogPostController extends MSController $model=new BlogPost('search'); $model->unsetAttributes(); // clear any default values - if (isset($_GET['BlogPost'])) { + if (isset($_GET['BlogPost'])) + { $model->attributes=$_GET['BlogPost']; } - $this->render('admin',array( - 'model'=>$model, - )); + $this->render('admin', + [ + 'model'=>$model, + ]); } /** @@ -190,7 +213,8 @@ class BlogPostController extends MSController public function loadModel($id) { $model=BlogPost::model()->findByPk($id); - if ($model===null) { + if ($model===null) + { throw new CHttpException(404,'The requested page does not exist.'); } return $model; @@ -207,4 +231,57 @@ class BlogPostController extends MSController Yii::app()->end(); } } + + //######################################################################### + //##################### Special Blogpost Controllers ###################### + //######################################################################### + + /** + * @param BlogPost $model + */ + protected function viewBlogpostProjectEulerBefunge($model) + { + $problems = EulerProblem::model()->findAll(['order'=>'Problemnumber']); + + $problemnumber = 0; + if (isset($_GET['problem']) AND is_numeric($_GET['problem'])) + $problemnumber = $_GET['problem']; + + $criteria=new CDbCriteria; + $criteria->condition='Problemnumber = ' . $problemnumber; + $currproblem = EulerProblem::model()->find($criteria); + + if (is_null($currproblem)) + { + $problemID = -1; + $currproblem = null; + } + else + { + $problemID = -1; + for($i = 0; $i < count($problems); $i++) + if ($problems[$i]->Problemnumber == $problemnumber) + { + $problemID = $i; + break; + } + } + + if ($problemID == -1) + { + $problemID = -1; + $currproblem = null; + } + + $this->render('view_ProjectEulerBefunge', + [ + 'model' => $model, + 'problems' => $problems, + 'currproblem' => $currproblem, + 'currproblemID' => $problemID, + ]); + } + + //######################################################################### + //######################################################################### } \ No newline at end of file diff --git a/www/protected/controllers/EulerProblemController.php b/www/protected/controllers/EulerProblemController.php new file mode 100644 index 0000000..080831d --- /dev/null +++ b/www/protected/controllers/EulerProblemController.php @@ -0,0 +1,169 @@ +array('index','view','create','update','admin','delete'), + 'users'=>array('@'), + ), + array('deny', + 'users'=>array('*'), + ), + ); + } + + /** + * Displays a particular model. + * @param integer $id the ID of the model to be displayed + */ + public function actionView($id) + { + $this->render('view',array( + 'model'=>$this->loadModel($id), + )); + } + + /** + * Creates a new model. + * If creation is successful, the browser will be redirected to the 'view' page. + */ + public function actionCreate() + { + $model=new EulerProblem; + + // Uncomment the following line if AJAX validation is needed + // $this->performAjaxValidation($model); + + if (isset($_POST['EulerProblem'])) { + $model->attributes=$_POST['EulerProblem']; + if ($model->save()) { + $this->redirect(array('view','id'=>$model->Problemnumber)); + } + } + + $this->render('create',array( + 'model'=>$model, + )); + } + + /** + * Updates a particular model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id the ID of the model to be updated + */ + public function actionUpdate($id) + { + $model=$this->loadModel($id); + + // Uncomment the following line if AJAX validation is needed + // $this->performAjaxValidation($model); + + if (isset($_POST['EulerProblem'])) { + $model->attributes=$_POST['EulerProblem']; + if ($model->save()) { + $this->redirect(array('view','id'=>$model->Problemnumber)); + } + } + + $this->render('update',array( + 'model'=>$model, + )); + } + + /** + * Deletes a particular model. + * If deletion is successful, the browser will be redirected to the 'admin' page. + * @param integer $id the ID of the model to be deleted + */ + public function actionDelete($id) + { + if (Yii::app()->request->isPostRequest) { + // we only allow deletion via POST request + $this->loadModel($id)->delete(); + + // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser + if (!isset($_GET['ajax'])) { + $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin')); + } + } else { + throw new CHttpException(400,'Invalid request. Please do not repeat this request again.'); + } + } + + /** + * Lists all models. + */ + public function actionIndex() + { + $dataProvider=new CActiveDataProvider('EulerProblem'); + $this->render('index',array( + 'dataProvider'=>$dataProvider, + )); + } + + /** + * Manages all models. + */ + public function actionAdmin() + { + $model=new EulerProblem('search'); + $model->unsetAttributes(); // clear any default values + if (isset($_GET['EulerProblem'])) { + $model->attributes=$_GET['EulerProblem']; + } + + $this->render('admin',array( + 'model'=>$model, + )); + } + + /** + * Returns the data model based on the primary key given in the GET variable. + * If the data model is not found, an HTTP exception will be raised. + * @param integer $id the ID of the model to be loaded + * @return EulerProblem the loaded model + * @throws CHttpException + */ + public function loadModel($id) + { + $model=EulerProblem::model()->findByPk($id); + if ($model===null) { + throw new CHttpException(404,'The requested page does not exist.'); + } + return $model; + } + + /** + * Performs the AJAX validation. + * @param EulerProblem $model the model to be validated + */ + protected function performAjaxValidation($model) + { + if (isset($_POST['ajax']) && $_POST['ajax']==='euler-problem-form') { + echo CActiveForm::validate($model); + Yii::app()->end(); + } + } +} \ No newline at end of file diff --git a/www/protected/controllers/MsmainController.php b/www/protected/controllers/MsmainController.php index a767b25..92d17c0 100644 --- a/www/protected/controllers/MsmainController.php +++ b/www/protected/controllers/MsmainController.php @@ -43,7 +43,7 @@ class MSMainController extends MSController /* @var $all_log Log[] */ $data = array(); - $data['program'] = ProgramHelper::GetDailyProg(); + $data['program'] = ProgramHelper::GetDailyProg(); //TODO-MS Show last BlogEntry $data['logs'] = $all_log; $this->render('index', $data); diff --git a/www/protected/models/BlogPost.php b/www/protected/models/BlogPost.php index d8091d6..e96a68a 100644 --- a/www/protected/models/BlogPost.php +++ b/www/protected/models/BlogPost.php @@ -8,6 +8,7 @@ * @property string $Date * @property string $Title * @property string $Content + * @property string $ControllerID * @property string $Visible * @property string $Enabled */ @@ -29,10 +30,10 @@ class BlogPost extends CActiveRecord // NOTE: you should only define rules for those attributes that // will receive user inputs. return array( - array('Date, Title, Content, Visible, Enabled', 'required'), + array('Date, Title, Content, ControllerID, Visible, Enabled', 'required'), array('Visible, Enabled', 'numerical', 'integerOnly'=>true), - array('ID, Date, Title, Content, Visible, Enabled', 'safe', 'on'=>'search'), + array('ID, Date, Title, Content, ControllerID, Visible, Enabled', 'safe', 'on'=>'search'), ); } @@ -57,6 +58,7 @@ class BlogPost extends CActiveRecord 'Date' => 'Date', 'Title' => 'Title', 'Content' => 'Content', + 'ControllerID' => 'ControllerID', 'Visible' => 'Visible', 'Enabled' => 'Enabled', ); @@ -82,6 +84,7 @@ class BlogPost extends CActiveRecord $criteria->compare('Date',$this->Date,true); $criteria->compare('Title',$this->Title,true); $criteria->compare('Content',$this->Content,true); + $criteria->compare('ControllerID',$this->ControllerID,true); $criteria->compare('Visible',$this->Visible,true); $criteria->compare('Enabled',$this->Enabled,true); @@ -167,4 +170,9 @@ class BlogPost extends CActiveRecord return $result; } + + public function isSpecialBlogPost() + { + return ! empty($this->ControllerID); + } } diff --git a/www/protected/models/EulerProblem.php b/www/protected/models/EulerProblem.php new file mode 100644 index 0000000..25796d1 --- /dev/null +++ b/www/protected/models/EulerProblem.php @@ -0,0 +1,177 @@ +true), + array('SolutionSteps, SolutionTime, SolutionValue', 'length', 'max'=>20), + array('Problemtitle', 'length', 'max'=>50), + + array('Problemnumber, Problemtitle, Problemdescription, Code, Explanation, AbbreviatedCode, SolutionSteps, SolutionTime, SolutionValue', 'safe', 'on'=>'search'), + ); + } + + /** + * @return array relational rules. + */ + public function relations() + { + // NOTE: you may need to adjust the relation name and the related + // class name for the relations automatically generated below. + return array( + ); + } + + /** + * @return array customized attribute labels (name=>label) + */ + public function attributeLabels() + { + return array( + 'Problemnumber' => 'Problemnumber', + 'Problemtitle' => 'Problemtitle', + 'Problemdescription' => 'Problemdescription', + 'Code' => 'Code', + 'Explanation' => 'Explanation', + 'AbbreviatedCode' => 'Abbreviated Code', + 'SolutionSteps' => 'Solution Steps', + 'SolutionTime' => 'Solution Time', + 'SolutionWidth' => 'Solution Width', + 'SolutionHeight' => 'Solution Height', + 'SolutionValue' => 'Solution Value', + ); + } + + /** + * Retrieves a list of models based on the current search/filter conditions. + * + * Typical usecase: + * - Initialize the model fields with values from filter form. + * - Execute this method to get CActiveDataProvider instance which will filter + * models according to data in model fields. + * - Pass data provider to CGridView, CListView or any similar widget. + * + * @return CActiveDataProvider the data provider that can return the models + * based on the search/filter conditions. + */ + public function search() + { + $criteria=new CDbCriteria; + + $criteria->compare('Problemnumber',$this->Problemnumber); + $criteria->compare('Problemtitle',$this->Problemdescription,true); + $criteria->compare('Problemdescription',$this->Problemdescription,true); + $criteria->compare('Code',$this->Code,true); + $criteria->compare('Explanation',$this->Explanation,true); + $criteria->compare('AbbreviatedCode',$this->AbbreviatedCode); + $criteria->compare('SolutionSteps',$this->SolutionSteps,true); + $criteria->compare('SolutionTime',$this->SolutionTime,true); + $criteria->compare('SolutionWidth',$this->SolutionWidth); + $criteria->compare('SolutionHeight',$this->SolutionHeight); + $criteria->compare('SolutionValue',$this->SolutionValue,true); + + return new CActiveDataProvider($this, array( + 'criteria'=>$criteria, + )); + } + + /** + * Returns the static model of the specified AR class. + * Please note that you should have this exact method in all your CActiveRecord descendants! + * @param string $className active record class name. + * @return EulerProblem the static model class + */ + public static function model($className=__CLASS__) + { + return parent::model($className); + } + + public function getSourcecodefile($absolute = true) + { + return ($absolute ? '/' : '') . 'data/blog/Befunge/Euler_Problem-' . str_pad($this->Problemnumber, 3, '0', STR_PAD_LEFT) . '.b93'; + } + + public function getTimeScore() + { + if ($this->SolutionTime < 100) // < 100ms + return EulerProblem::TIMELEVEL_PERFECT; + + else if ($this->SolutionTime < 15 * 1000) // < 5s + return EulerProblem::TIMELEVEL_GOOD; + + else if ($this->SolutionTime < 60 * 1000) // < 1min + return EulerProblem::TIMELEVEL_OK; + + else if ($this->SolutionTime < 5 * 60 * 1000) // < 5min + return EulerProblem::TIMELEVEL_BAD; + + else + return EulerProblem::TIMELEVEL_FAIL; + } + + public function isBefunge93() + { + return $this->SolutionWidth <= 80 AND $this->SolutionHeight <= 25; + } + + public function generateMarkdown() + { + $num_padded = str_pad($this->Problemnumber, 3, '0', STR_PAD_LEFT); + + return + 'Problem [' . $num_padded. '](http://projecteuler.net/problem=' . $num_padded . '): ' . $this->Problemtitle . PHP_EOL . + '--------' . PHP_EOL . + '' . PHP_EOL . + MsHelper::encloseLines($this->Problemdescription, '> ', '') . PHP_EOL . + '' . PHP_EOL . + '```befunge' . PHP_EOL . + $this->Code . PHP_EOL . + '```' . PHP_EOL . + '[Download](/data/blog/Befunge/Euler_Problem-' . $num_padded . '.b93)' . PHP_EOL . + '' . PHP_EOL . + $this->Explanation . PHP_EOL . + '' . PHP_EOL . + '**Interpreter steps:** `' . number_format($this->SolutionSteps, 0, null, ',') . '` ' . PHP_EOL . + '**Execution time** ([BefunExec](/programs/view/BefunGen)): `' . number_format($this->SolutionTime, 0, null, ',') . '` ms' . (($this->SolutionTime < 1000) ? (' ') : (' *(= ' . MsHelper::formatMilliseconds($this->SolutionTime) . ')* ')) . PHP_EOL . + '**Program size:** `' . $this->SolutionWidth . 'x' . $this->SolutionHeight . '` ' . PHP_EOL . + '**Solution:** `' . number_format($this->SolutionValue, 0, null, ',') . '` '; + } +} diff --git a/www/protected/models/HighscoreEntries.php b/www/protected/models/HighscoreEntries.php index 7d93a55..41a437e 100644 --- a/www/protected/models/HighscoreEntries.php +++ b/www/protected/models/HighscoreEntries.php @@ -37,7 +37,6 @@ class HighscoreEntries extends CActiveRecord array('PLAYER, IP', 'length', 'max'=>41), array('CHECKSUM', 'length', 'max'=>32), // The following rule is used by search(). - // @todo Please remove those attributes that should not be searched. array('GAME_ID, POINTS, PLAYER, PLAYERID, CHECKSUM, TIMESTAMP, IP', 'safe', 'on'=>'search'), ); } diff --git a/www/protected/models/HighscoreGames.php b/www/protected/models/HighscoreGames.php index 3255a16..bc5c4b1 100644 --- a/www/protected/models/HighscoreGames.php +++ b/www/protected/models/HighscoreGames.php @@ -81,8 +81,6 @@ class HighscoreGames extends CActiveRecord */ public function search() { - // @todo Please modify the following code to remove attributes that should not be searched. - $criteria=new CDbCriteria; $criteria->compare('ID',$this->ID); diff --git a/www/protected/views/blogpost/_form.php b/www/protected/views/blogpost/_form.php index 01faf87..5f73aa2 100644 --- a/www/protected/views/blogpost/_form.php +++ b/www/protected/views/blogpost/_form.php @@ -30,6 +30,8 @@ textAreaControlGroup($model,'Content',array('rows'=>30,'span'=>8)); ?> + textFieldControlGroup($model,'ControllerID',array('span'=>8)); ?> + isNewRecord) echo $form->textFieldControlGroup($model,'Visible',array('span'=>5, 'value' => '1')); diff --git a/www/protected/views/blogpost/_search.php b/www/protected/views/blogpost/_search.php index 2e415df..a2e6e8a 100644 --- a/www/protected/views/blogpost/_search.php +++ b/www/protected/views/blogpost/_search.php @@ -17,6 +17,8 @@ textAreaControlGroup($model,'Content',array('rows'=>6,'span'=>8)); ?> + textFieldControlGroup($model,'ControllerID',array('span'=>5)); ?> + textFieldControlGroup($model,'Visible',array('span'=>5)); ?> textFieldControlGroup($model,'Enabled',array('span'=>5)); ?> diff --git a/www/protected/views/blogpost/_view.php b/www/protected/views/blogpost/_view.php index d46e429..2d1b395 100644 --- a/www/protected/views/blogpost/_view.php +++ b/www/protected/views/blogpost/_view.php @@ -21,6 +21,11 @@ Content); ?>
+ getAttributeLabel('ControllerID')); ?>: + ControllerID); ?> +
+ + getAttributeLabel('Visible')); ?>: Visible); ?>
diff --git a/www/protected/views/blogpost/view_ProjectEulerBefunge.php b/www/protected/views/blogpost/view_ProjectEulerBefunge.php new file mode 100644 index 0000000..091e1a1 --- /dev/null +++ b/www/protected/views/blogpost/view_ProjectEulerBefunge.php @@ -0,0 +1,168 @@ + + +pageTitle = 'Blogpost: ' . $model->Title . ' - ' . Yii::app()->name; + +if ($currproblemID < 0) +{ + $this->breadcrumbs = array( + 'Blog' => ['/blog'], + $model->Title, + ); +} +else +{ + $this->breadcrumbs = array( + 'Blog' => ['/blog'], + $model->Title => [$model->getLink()], + 'Problem_' . str_pad($problems[$currproblemID]->Problemnumber, 3, '0', STR_PAD_LEFT), + ); +} + + +array_push($this->css_files, "/css/blogpost_ProjectEulerBefunge_style.css"); + +?> + +
+ + + + +
+ Fork me on GitHub + +

Title ?>

+ +

+ +

A lot of you probably know Project Euler.
+ For those who don't here a short explanation: Project Euler is a collection of mathematical/programming problems. + Most problems consist of finding a single number and are solved by writing a program in the programming language of your choice.

+

Most people solve these by using normal languages like C, Java, Phyton, Haskell etc. + But you can also go a step further and try solving it with a little bit more exotic languages.

+

So here are my solutions written in Befunge

+
+

Note:
+ Similar to most Befunge content on this site I only used the Befunge-93 instruction-set but ignored the 80x25 size restriction. + (Even so most programs here don't get this big.)

+
+ + + + + + + + + + + + + + ' . "\r\n"; + + echo '\r\n"; + echo '\r\n"; + echo '\r\n"; + + if ($problem->isBefunge93()) + echo '\r\n"; + else + echo '\r\n"; + + echo '\r\n"; + + echo "\r\n"; + } + ?> + +
NumberTitleTimeSizeSolution (hover to reveal)
' . $problem->Problemnumber . "' . $problem->Problemtitle . "
' . MsHelper::formatMilliseconds($problem->SolutionTime) . "
' . $problem->SolutionWidth . 'x' . $problem->SolutionHeight . '
Bef-93
' . "
' . $problem->SolutionWidth . 'x' . $problem->SolutionHeight . '
Bef-98
' . "
' . number_format($problem->SolutionValue, 0, null, ',') . "
+
+ + +
+ = 0) + { + echo 'Fork me on GitHub'; + + echo "

$model->Title

"; + + echo ParsedownHelper::parse($currproblem->generateMarkdown()); + } + else + { + echo "

Problems:

"; + } + ?> + + str_pad($problems[$i]->Problemnumber, 3, '0', STR_PAD_LEFT), + 'url' => '?problem=' . $problems[$i]->Problemnumber, + 'disabled' => false, + 'active' => $currproblemID == $i, + ]); + else + array_push($pagination, + [ + 'label' => str_pad($i+1, 3, '0', STR_PAD_LEFT), + 'url' => '#', + 'disabled' => true, + 'active' => false, + ]); + + if ((($i+1) % 20 == 0)) + { + echo TbHtml::pagination($pagination, ['align' => TbHtml::PAGINATION_ALIGN_CENTER]); + $pagination = array(); + } + } + echo TbHtml::pagination($pagination, ['align' => TbHtml::PAGINATION_ALIGN_CENTER]); + ?> + +
+
+ Title; ?> +
+
+ getDateTime()->format('d.m.Y'); ?> +
+
+
+ +
+ widget( + 'ext.YiiDisqusWidget.YiiDisqusWidget', + [ + 'shortname' => 'mikescher-de', + 'identifier' => 'blog/view/' + $model->ID, + 'title' => $model->Title, + 'url' => $model->getAbsoluteLink(), + 'category_id' => '3253401', // = blog/view + ] + ); + ?> +
+ +
diff --git a/www/protected/views/eulerProblem/_form.php b/www/protected/views/eulerProblem/_form.php new file mode 100644 index 0000000..99350b0 --- /dev/null +++ b/www/protected/views/eulerProblem/_form.php @@ -0,0 +1,57 @@ + + +
+ + beginWidget('bootstrap.widgets.TbActiveForm', array( + 'id'=>'euler-problem-form', + // Please note: When you enable ajax validation, make sure the corresponding + // controller action is handling ajax validation correctly. + // There is a call to performAjaxValidation() commented in generated controller code. + // See class documentation of CActiveForm for details on this. + 'enableAjaxValidation'=>false, +)); ?> + +

Fields with * are required.

+ + errorSummary($model); ?> + + textFieldControlGroup($model,'Problemnumber',array('span'=>8)); ?> + + textFieldControlGroup($model,'Problemtitle',array('span'=>5,'maxlength'=>50)); ?> + + textAreaControlGroup($model,'Problemdescription',array('rows'=>6,'span'=>8)); ?> + + textAreaControlGroup($model,'Code',array('rows'=>6,'span'=>8)); ?> + + textAreaControlGroup($model,'Explanation',array('rows'=>6,'span'=>8)); ?> + + isNewRecord) + echo $form->textFieldControlGroup($model,'AbbreviatedCode',array('span'=>5, 'value' => '0')); + else + echo $form->textFieldControlGroup($model,'AbbreviatedCode',array('span'=>5)); + ?> + + textFieldControlGroup($model,'SolutionSteps',array('span'=>5,'maxlength'=>20)); ?> + + textFieldControlGroup($model,'SolutionTime',array('span'=>5,'maxlength'=>20)); ?> + + textFieldControlGroup($model,'SolutionWidth',array('span'=>5)); ?> + textFieldControlGroup($model,'SolutionHeight',array('span'=>5)); ?> + + textFieldControlGroup($model,'SolutionValue',array('span'=>5,'maxlength'=>20)); ?> + +
+ isNewRecord ? 'Create' : 'Save',array( + 'color'=>TbHtml::BUTTON_COLOR_PRIMARY, + 'size'=>TbHtml::BUTTON_SIZE_LARGE, + )); ?> +
+ + endWidget(); ?> + +
\ No newline at end of file diff --git a/www/protected/views/eulerProblem/_search.php b/www/protected/views/eulerProblem/_search.php new file mode 100644 index 0000000..b93f60b --- /dev/null +++ b/www/protected/views/eulerProblem/_search.php @@ -0,0 +1,41 @@ + + +
+ + beginWidget('bootstrap.widgets.TbActiveForm', array( + 'action'=>Yii::app()->createUrl($this->route), + 'method'=>'get', +)); ?> + + textFieldControlGroup($model,'Problemnumber',array('span'=>5)); ?> + + textFieldControlGroup($model,'Problemtitle',array('span'=>5,'maxlength'=>50)); ?> + + textAreaControlGroup($model,'Problemdescription',array('rows'=>6,'span'=>8)); ?> + + textAreaControlGroup($model,'Code',array('rows'=>6,'span'=>8)); ?> + + textAreaControlGroup($model,'Explanation',array('rows'=>6,'span'=>8)); ?> + + textFieldControlGroup($model,'AbbreviatedCode',array('span'=>5)); ?> + + textFieldControlGroup($model,'SolutionSteps',array('span'=>5,'maxlength'=>20)); ?> + + textFieldControlGroup($model,'SolutionTime',array('span'=>5,'maxlength'=>20)); ?> + + textFieldControlGroup($model,'SolutionWidth',array('span'=>5)); ?> + textFieldControlGroup($model,'SolutionHeight',array('span'=>5)); ?> + + textFieldControlGroup($model,'SolutionValue',array('span'=>5,'maxlength'=>20)); ?> + +
+ TbHtml::BUTTON_COLOR_PRIMARY,));?> +
+ + endWidget(); ?> + +
\ No newline at end of file diff --git a/www/protected/views/eulerProblem/_view.php b/www/protected/views/eulerProblem/_view.php new file mode 100644 index 0000000..0965977 --- /dev/null +++ b/www/protected/views/eulerProblem/_view.php @@ -0,0 +1,55 @@ + + +
+ + getAttributeLabel('Problemnumber')); ?>: + Problemnumber),array('view','id'=>$data->Problemnumber)); ?> +
+ + getAttributeLabel('Problemtitle')); ?>: + Problemtitle)); ?> +
+ + getAttributeLabel('Problemdescription')); ?>: + Problemdescription); ?> +
+ + getAttributeLabel('Code')); ?>: + Code); ?> +
+ + getAttributeLabel('Explanation')); ?>: + Explanation); ?> +
+ + getAttributeLabel('AbbreviatedCode')); ?>: + AbbreviatedCode); ?> +
+ + getAttributeLabel('SolutionSteps')); ?>: + SolutionSteps); ?> +
+ + getAttributeLabel('SolutionWidth')); ?>: + SolutionTime); ?> +
+ + getAttributeLabel('SolutionHeight')); ?>: + SolutionTime); ?> +
+ + getAttributeLabel('SolutionTime')); ?>: + SolutionTime); ?> +
+ + getAttributeLabel('SolutionValue')); ?>: + SolutionValue); ?> +
+ + */ ?> + +
\ No newline at end of file diff --git a/www/protected/views/eulerProblem/admin.php b/www/protected/views/eulerProblem/admin.php new file mode 100644 index 0000000..5859edc --- /dev/null +++ b/www/protected/views/eulerProblem/admin.php @@ -0,0 +1,64 @@ +breadcrumbs=array( + 'Euler Problems'=>array('index'), + 'Manage', +); + +$this->menu=array( + array('label'=>'List EulerProblem', 'url'=>array('index')), + array('label'=>'Create EulerProblem', 'url'=>array('create')), +); + +Yii::app()->clientScript->registerScript('search', " +$('.search-button').click(function(){ + $('.search-form').toggle(); + return false; +}); +$('.search-form form').submit(function(){ + $('#euler-problem-grid').yiiGridView('update', { + data: $(this).serialize() + }); + return false; +}); +"); +?> + +

Manage Euler Problems

+ +

+ You may optionally enter a comparison operator (<, <=, >, >=, + <> +or =) at the beginning of each of your search values to specify how the comparison should be done. +

+ +'search-button btn')); ?> + + +widget('bootstrap.widgets.TbGridView',array( + 'id'=>'euler-problem-grid', + 'dataProvider'=>$model->search(), + 'filter'=>$model, + 'columns'=>array( + 'Problemnumber', + 'Problemdescription', + 'Code', + 'Explanation', + 'AbbreviatedCode', + 'SolutionSteps', + /* + 'SolutionTime', + 'SolutionValue', + */ + array( + 'class'=>'bootstrap.widgets.TbButtonColumn', + ), + ), +)); ?> \ No newline at end of file diff --git a/www/protected/views/eulerProblem/create.php b/www/protected/views/eulerProblem/create.php new file mode 100644 index 0000000..e6a20f2 --- /dev/null +++ b/www/protected/views/eulerProblem/create.php @@ -0,0 +1,20 @@ + + +breadcrumbs=array( + 'Euler Problems'=>array('index'), + 'Create', +); + +$this->menu=array( + array('label'=>'List EulerProblem', 'url'=>array('index')), + array('label'=>'Manage EulerProblem', 'url'=>array('admin')), +); +?> + +

Create EulerProblem

+ +renderPartial('_form', array('model'=>$model)); ?> \ No newline at end of file diff --git a/www/protected/views/eulerProblem/index.php b/www/protected/views/eulerProblem/index.php new file mode 100644 index 0000000..2d9b871 --- /dev/null +++ b/www/protected/views/eulerProblem/index.php @@ -0,0 +1,35 @@ + + +breadcrumbs=array( + 'Euler Problems', +); + +$this->menu=array( + array('label'=>'Create EulerProblem','url'=>array('create')), + array('label'=>'Manage EulerProblem','url'=>array('admin')), +); +?> + +

Euler Problems

+ +widget('bootstrap.widgets.TbGridView',array( + 'type'=>'striped bordered condensed', + + 'dataProvider'=>$dataProvider, + + 'columns'=>array( + 'Problemnumber', + 'Problemtitle', + 'Problemdescription', + 'AbbreviatedCode', + 'SolutionWidth', + 'SolutionHeight', + 'SolutionSteps', + 'SolutionTime', + 'SolutionValue', + ), +)); ?> \ No newline at end of file diff --git a/www/protected/views/eulerProblem/update.php b/www/protected/views/eulerProblem/update.php new file mode 100644 index 0000000..b7ccbbf --- /dev/null +++ b/www/protected/views/eulerProblem/update.php @@ -0,0 +1,23 @@ + + +breadcrumbs=array( + 'Euler Problems'=>array('index'), + '#' . $model->Problemnumber=>array('view','id'=>$model->Problemnumber), + 'Update', +); + +$this->menu=array( + array('label'=>'List EulerProblem', 'url'=>array('index')), + array('label'=>'Create EulerProblem', 'url'=>array('create')), + array('label'=>'View EulerProblem', 'url'=>array('view', 'id'=>$model->Problemnumber)), + array('label'=>'Manage EulerProblem', 'url'=>array('admin')), +); +?> + +

Update EulerProblem Problemnumber; ?>

+ +renderPartial('_form', array('model'=>$model)); ?> \ No newline at end of file diff --git a/www/protected/views/eulerProblem/view.php b/www/protected/views/eulerProblem/view.php new file mode 100644 index 0000000..37c4dc7 --- /dev/null +++ b/www/protected/views/eulerProblem/view.php @@ -0,0 +1,38 @@ + + +breadcrumbs=array( + 'Euler Problems'=>array('index'), + '#' . $model->Problemnumber, +); + +$this->menu=array( + array('label'=>'List EulerProblem', 'url'=>array('index')), + array('label'=>'Create EulerProblem', 'url'=>array('create')), + array('label'=>'Update EulerProblem', 'url'=>array('update', 'id'=>$model->Problemnumber)), + array('label'=>'Delete EulerProblem', 'url'=>'#', 'linkOptions'=>array('submit'=>array('delete','id'=>$model->Problemnumber),'confirm'=>'Are you sure you want to delete this item?')), + array('label'=>'Manage EulerProblem', 'url'=>array('admin')), +); +?> + +

View EulerProblem #Problemnumber; ?>

+ +widget('zii.widgets.CDetailView',array( + 'htmlOptions' => array( + 'class' => 'table table-striped table-condensed table-hover', + ), + 'data'=>$model, + 'attributes'=>array( + 'Problemnumber', + 'Problemdescription', + 'Code', + 'Explanation', + 'AbbreviatedCode', + 'SolutionSteps', + 'SolutionTime', + 'SolutionValue', + ), +)); ?> \ No newline at end of file diff --git a/www/protected/views/layouts/main.php b/www/protected/views/layouts/main.php index 0b02ca5..0d5ef76 100644 --- a/www/protected/views/layouts/main.php +++ b/www/protected/views/layouts/main.php @@ -19,9 +19,13 @@ bootstrap->register(); ?> - - - + + css_files as $file) + { + echo "\r\n"; + } + ?>