├── .htaccess
├── Dockerfile
├── LICENSE.txt
├── README.md
├── conf.php
├── countries.sql
├── css
├── bootstrap-theme.min.css
├── bootstrap.min.css
├── bs_cm.php
├── codemirror.css
├── common_bs.css
├── highlight.css
└── task
│ └── view.css
├── ctl
├── .htaccess
├── Login.php
├── Logout.php
├── Main.php
├── Wiki.php
├── _hookBefore.php
├── api
│ └── Weekbest.php
├── forum
│ ├── Delete.php
│ ├── Edit.php
│ ├── Main.php
│ ├── Newtopic.php
│ ├── Post.php
│ ├── Rename.php
│ ├── Topic.php
│ ├── Update.php
│ └── View.php
├── mess
│ └── Hall.php
├── task
│ ├── Attempt2.php
│ ├── Edit.php
│ ├── List.php
│ ├── Preparedata.php
│ ├── Save.php
│ ├── Solution.php
│ ├── Solvers.php
│ ├── Star.php
│ ├── Success.php
│ ├── Testchecker.php
│ ├── Text.php
│ ├── View.php
│ └── tag
│ │ ├── Assign.php
│ │ ├── Edit.php
│ │ ├── List.php
│ │ └── Update.php
├── tools
│ └── Calcpoints.php
├── user
│ ├── Profile.php
│ ├── Ranking.php
│ ├── Settings.php
│ ├── Unsolved.php
│ └── settings
│ │ ├── Avatar.php
│ │ ├── Chname.php
│ │ ├── Country.php
│ │ ├── Email.php
│ │ ├── Info.php
│ │ └── Password.php
└── wiki
│ ├── Edit.php
│ └── Save.php
├── data
└── db-ip.txt
├── dbinit.sql
├── docker-build.sh
├── docker-run.sh
├── fragments
├── .htaccess
├── countryselect.html
├── cssandjs.html
├── flash.html
├── footer.html
├── forumform.html
├── langselect.html
├── main
│ ├── bottomnote.html
│ ├── image.html
│ ├── lastforum.html
│ ├── lasttasks.html
│ ├── login.html
│ ├── middlenote.html
│ └── rank.html
├── menu-bs.html
├── metas.html
├── rankline.html
├── tasklist
│ └── notice.html
└── taskview
│ ├── badattempt.html
│ ├── errorsmodal.html
│ ├── runtools.html
│ └── solcaption.html
├── img
├── facade.gif
├── flags
│ └── zz.gif
├── logingg.png
├── logingh.png
├── logout.png
├── profile.png
├── random.png
├── search2.png
└── settings.png
├── index.php
├── js
├── _ace
│ ├── ace.js
│ ├── mode-c_cpp.js
│ ├── mode-csharp.js
│ ├── mode-golang.js
│ ├── mode-haskell.js
│ ├── mode-java.js
│ ├── mode-javascript.js
│ ├── mode-julia.js
│ ├── mode-lua.js
│ ├── mode-perl.js
│ ├── mode-php.js
│ ├── mode-plain_text.js
│ ├── mode-python.js
│ ├── mode-ruby.js
│ ├── mode-rust.js
│ ├── mode-scala.js
│ ├── mode-sql.js
│ ├── mode-swift.js
│ └── test-it.html
├── _cm
│ ├── clike.js
│ ├── codemirror.js
│ ├── markdown.js
│ ├── matchbrackets.js
│ ├── php.js
│ └── xml.js
├── bootstrap.min.js
├── common.js
├── highlight.js
├── jq.js
├── jq_bs_cm.php
├── task
│ ├── _view.js
│ └── edit.js
└── wiki
│ └── edit.js
├── layouts
├── .htaccess
└── default_bs.html
├── module
├── .htaccess
├── Context.php
├── auth
│ └── Auth.php
├── dao
│ ├── ChallengesDao.php
│ ├── ForumTopicsDao.php
│ ├── MysqlDao.php
│ ├── TasksDao.php
│ ├── UserDataDao.php
│ └── UserTasksDao.php
├── lib
│ └── Markdown_Parser.php
├── service
│ ├── CertService.php
│ ├── ChallengeService.php
│ ├── CheatService.php
│ ├── ForumService.php
│ ├── FriendService.php
│ ├── LangService.php
│ ├── LocaleService.php
│ ├── LoginService.php
│ ├── MiscService.php
│ ├── MsgService.php
│ ├── StrUtils.php
│ ├── TaskService.php
│ └── UserService.php
└── sys
│ ├── Elems.php
│ ├── ProtoContext.php
│ └── Util.php
├── pages
├── .htaccess
├── error.php
├── error403.php
├── error404.php
├── forum
│ ├── edit.php
│ ├── list.php
│ ├── main.php
│ ├── newtopic.php
│ ├── noaccess.php
│ ├── topic.php
│ └── view.php
├── login.php
├── main.php
├── mess
│ └── hall.php
├── message.php
├── task
│ ├── edit.php
│ ├── list.php
│ ├── solution.php
│ ├── solvers.php
│ ├── success.php
│ ├── tag
│ │ ├── edit.php
│ │ └── list.php
│ └── view.php
├── user
│ ├── profile.php
│ ├── ranking.php
│ ├── settings.php
│ └── unsolved.php
├── wiki.php
└── wiki
│ ├── edit.php
│ └── index.php
├── sqlexec.php
└── taskinit.sql
/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine on
2 |
3 | #RewriteRule ^(.*)$ "http\:\/\/localhost\:8080\/$1" [R=301,L]
4 |
5 | RewriteRule ^index$ index.php
6 | RewriteRule ^index\/([\w]+)\/?$ index.php?page=$1 [QSA]
7 | RewriteRule ^index\/([\w]+)\/([A-Za-z\d\-\.]+)\/?$ index.php?page=$1¶m=$2 [QSA]
8 | RewriteRule ^index\/([\w]+)\/([A-Za-z]+)\_([A-Za-z\d\-]+)\/?$ index.php?page=$1&$2=$3 [QSA]
9 |
10 | ErrorDocument 403 /index/error404
11 | ErrorDocument 404 /index/error404
12 | Options -Indexes
13 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:8.3-apache
2 |
3 | RUN docker-php-ext-install mysqli && a2enmod rewrite \
4 | && apt-get update && apt-get install -y mariadb-server \
5 | && mkdir /run/mysqld \
6 | && chmod a+s /usr/bin/mariadb
7 |
8 | CMD ["/bin/bash", "-c", "coproc mariadbd --user=root && sleep 5 && apache2-foreground"]
9 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | CodeAbbey License
2 |
3 | Copyright (c) 2013 Rodion Gorkovenko
4 |
5 | Permission is granted to run, study, share, modify this software,
6 | free of charge, to anyone, provided the following condition is met:
7 |
8 | 1. The reference to original repository https://github.com/codeabbey/src
9 | should be retained in unobscured way in user-facing interface (e.g.
10 | link with words "based upon CodeAbbey sources" in the footer of every web-page)
11 |
12 | 2. Redistributed copies and derived works should contain the above copyright
13 | notice and the link to original repository https://github.com/codeabbey/src
14 |
15 | The motivation is that any end-user may in turn obtain the copy of the original
16 | software. No conditions on publishing any changes, improvements, additions in
17 | derived works are imposed.
18 |
19 | The software is provided "AS IS", with no warranty of any kind. Reusing it you
20 | agree that the author is not responsible for any effects due to its use or misuse.
21 |
--------------------------------------------------------------------------------
/conf.php:
--------------------------------------------------------------------------------
1 | elems->conf->modrewrite = true;
6 |
7 | $ctx->elems->conf->mysql = array(
8 | 'host' => '127.0.0.1',
9 | 'port' => '3306',
10 | 'username' => 'causer',
11 | 'password' => 'somepwd',
12 | 'db' => 'ca',
13 | 'prefix' => 'pfx_',
14 | 'charset' => 'utf8'
15 | );
16 |
17 | $ctx->elems->conf->projectName = 'CodeAbbey';
18 | $ctx->elems->conf->title = "{$ctx->elems->conf->projectName} - programming problems";
19 | $ctx->elems->conf->descr = 'Collection of free programming puzzles';
20 | $ctx->elems->conf->descrSuffix = 'Programming problems for beginners';
21 | $ctx->elems->conf->author = 'Rodion Gorkovenko';
22 | $ctx->elems->conf->mainImage = aurl('img/facade.gif');
23 | $ctx->elems->conf->motto = 'We believe in three things, which lead to success: Practice, Practice and Practice!';
24 | $ctx->elems->conf->copyright = '© 2013 - ' . date('Y') . ', Rodion Gorkovenko';
25 | $ctx->elems->conf->defTaskSort = 'id1';
26 | $ctx->elems->conf->singleForum = false;
27 | $ctx->elems->conf->nameChangeLevel = 125;
28 | $ctx->elems->conf->personalInfoLevel = 25;
29 |
30 | $ctx->elems->conf->taskVolumes = array('simple' => 'Simple', 'advanced' => 'Advanced', 'special' => 'Special');
31 |
32 | $ctx->elems->conf->custFrag = array(
33 | 'adblock' => '',
34 | 'user_extraconfig' => '',
35 | );
36 |
37 | $ctx->elems->conf->custSvc = array(
38 | );
39 |
40 | $ctx->elems->conf->logging = array('activity' => false);
41 |
42 | $ctx->elems->conf->languages = array("c/c++" => "C/C++", "python" => "Python", "go" => "Go",
43 | "java" => "Java", "c#" => "C#", "javascript" => "JavaScript", "other" => "Other");
44 |
45 | $ctx->elems->conf->passwordSalt = 'salt#cadabraabra';
46 | $ctx->elems->conf->emailSalt = 'salt#racadabraab';
47 |
48 | $ctx->elems->conf->calcPointsSecret = null;
49 | $ctx->elems->conf->viewSolutionSecret = 'baracada';
50 | ?>
51 |
--------------------------------------------------------------------------------
/countries.sql:
--------------------------------------------------------------------------------
1 | use ca;
2 |
3 | insert into pfx_countries (code, title) values ('AD','Andorra'),('AE','United Arab Emirates'),('AF','Afghanistan'),('AG','Antigua & Barbuda'),('AI','Anguilla'),('AL','Albania');
4 | insert into pfx_countries (code, title) values ('AM','Armenia'),('AN','Netherlands Antilles'),('AO','Angola'),('AQ','Antarctica'),('AR','Argentina'),('AS','American Samoa'),('AT','Austria');
5 | insert into pfx_countries (code, title) values ('AU','Australia'),('AW','Aruba'),('AZ','Azerbaijan'),('BA','Bosnia and Herzegovina'),('BB','Barbados'),('BD','Bangladesh'),('BE','Belgium');
6 | insert into pfx_countries (code, title) values ('BF','Burkina Faso'),('BG','Bulgaria'),('BH','Bahrain'),('BI','Burundi'),('BJ','Benin'),('BM','Bermuda'),('BN','Brunei Darussalam');
7 | insert into pfx_countries (code, title) values ('BO','Bolivia'),('BR','Brazil'),('BS','Bahama'),('BT','Bhutan'),('BV','Bouvet Island'),('BW','Botswana'),('BY','Belarus'),('BZ','Belize');
8 | insert into pfx_countries (code, title) values ('CA','Canada'),('CC','Cocos (Keeling) Islands'),('CF','Central African Republic'),('CG','Congo'),('CH','Switzerland'),('CI','Cote D''ivoire (Ivory Coast)');
9 | insert into pfx_countries (code, title) values ('CK','Cook Iislands'),('CL','Chile'),('CM','Cameroon'),('CN','China'),('CO','Colombia'),('CR','Costa Rica'),('CU','Cuba'),('CV','Cape Verde');
10 | insert into pfx_countries (code, title) values ('CX','Christmas Island'),('CY','Cyprus'),('CZ','Czech Republic'),('DE','Germany'),('DJ','Djibouti'),('DK','Denmark'),('DM','Dominica');
11 | insert into pfx_countries (code, title) values ('DO','Dominican Republic'),('DZ','Algeria'),('EC','Ecuador'),('EE','Estonia'),('EG','Egypt'),('EH','Western Sahara'),('ER','Eritrea');
12 | insert into pfx_countries (code, title) values ('ES','Spain'),('ET','Ethiopia'),('FI','Finland'),('FJ','Fiji'),('FK','Falkland Islands (Malvinas)'),('FM','Micronesia'),('FO','Faroe Islands');
13 | insert into pfx_countries (code, title) values ('FR','France'),('FX','France, Metropolitan'),('GA','Gabon'),('GB','United Kingdom (Great Britain)'),('GD','Grenada'),('GE','Georgia');
14 | insert into pfx_countries (code, title) values ('GF','French Guiana'),('GH','Ghana'),('GI','Gibraltar'),('GL','Greenland'),('GM','Gambia'),('GN','Guinea'),('GP','Guadeloupe'),('GQ','Equatorial Guinea');
15 | insert into pfx_countries (code, title) values ('GR','Greece'),('GS','South Georgia and the South Sandwich Islands'),('GT','Guatemala'),('GU','Guam'),('GW','Guinea-Bissau'),('GY','Guyana');
16 | insert into pfx_countries (code, title) values ('HK','Hong Kong'),('HM','Heard & McDonald Islands'),('HN','Honduras'),('HR','Croatia'),('HT','Haiti'),('HU','Hungary'),('ID','Indonesia');
17 | insert into pfx_countries (code, title) values ('IE','Ireland'),('IL','Israel'),('IN','India'),('IO','British Indian Ocean Territory'),('IQ','Iraq'),('IR','Islamic Republic of Iran');
18 | insert into pfx_countries (code, title) values ('IS','Iceland'),('IT','Italy'),('JM','Jamaica'),('JO','Jordan'),('JP','Japan'),('KE','Kenya'),('KG','Kyrgyzstan'),('KH','Cambodia'),('KI','Kiribati');
19 | insert into pfx_countries (code, title) values ('KM','Comoros'),('KN','St. Kitts and Nevis'),('KP','Democratic People''s Republic of Korea'),('KR','Republic of Korea'),('KW','Kuwait');
20 | insert into pfx_countries (code, title) values ('KY','Cayman Islands'),('KZ','Kazakhstan'),('LA','Lao People''s Democratic Republic'),('LB','Lebanon'),('LC','Saint Lucia'),('LI','Liechtenstein');
21 | insert into pfx_countries (code, title) values ('LK','Sri Lanka'),('LR','Liberia'),('LS','Lesotho'),('LT','Lithuania'),('LU','Luxembourg'),('LV','Latvia'),('LY','Libyan Arab Jamahiriya');
22 | insert into pfx_countries (code, title) values ('MA','Morocco'),('MC','Monaco'),('MD','Republic of Moldova'),('MG','Madagascar'),('MH','Marshall Islands'),('ML','Mali'),('MM','Myanmar');
23 | insert into pfx_countries (code, title) values ('MN','Mongolia'),('MO','Macau'),('MP','Northern Mariana Islands'),('MQ','Martinique'),('MR','Mauritania'),('MS','Monserrat'),('MT','Malta');
24 | insert into pfx_countries (code, title) values ('MU','Mauritius'),('MV','Maldives'),('MW','Malawi'),('MX','Mexico'),('MY','Malaysia'),('MZ','Mozambique'),('NA','Nambia'),('NC','New Caledonia');
25 | insert into pfx_countries (code, title) values ('NE','Niger'),('NF','Norfolk Island'),('NG','Nigeria'),('NI','Nicaragua'),('NL','Netherlands'),('NO','Norway'),('NP','Nepal'),('NR','Nauru');
26 | insert into pfx_countries (code, title) values ('NU','Niue'),('NZ','New Zealand'),('OM','Oman'),('PA','Panama'),('PE','Peru'),('PF','French Polynesia'),('PG','Papua New Guinea'),('PH','Philippines');
27 | insert into pfx_countries (code, title) values ('PK','Pakistan'),('PL','Poland'),('PM','St. Pierre & Miquelon'),('PN','Pitcairn'),('PR','Puerto Rico'),('PT','Portugal'),('PW','Palau'),('PY','Paraguay');
28 | insert into pfx_countries (code, title) values ('QA','Qatar'),('RE','Reunion'),('RO','Romania'),('RU','Russian Federation'),('RW','Rwanda'),('SA','Saudi Arabia'),('SB','Solomon Islands'),('SC','Seychelles');
29 | insert into pfx_countries (code, title) values ('SD','Sudan'),('SE','Sweden'),('SG','Singapore'),('SH','St. Helena'),('SI','Slovenia'),('SJ','Svalbard & Jan Mayen Islands'),('SK','Slovakia'),('RS','Serbia');
30 | insert into pfx_countries (code, title) values ('SL','Sierra Leone'),('SM','San Marino'),('SN','Senegal'),('SO','Somalia'),('SR','Suriname'),('ST','Sao Tome & Principe'),('SV','El Salvador');
31 | insert into pfx_countries (code, title) values ('SY','Syrian Arab Republic'),('SZ','Swaziland'),('TC','Turks & Caicos Islands'),('TD','Chad'),('TF','French Southern Territories'),('TG','Togo');
32 | insert into pfx_countries (code, title) values ('TH','Thailand'),('TJ','Tajikistan'),('TK','Tokelau'),('TM','Turkmenistan'),('TN','Tunisia'),('TO','Tonga'),('TP','East Timor'),('TR','Turkey');
33 | insert into pfx_countries (code, title) values ('TT','Trinidad & Tobago'),('TV','Tuvalu'),('TW','Taiwan'),('TZ','United Republic of Tanzania'),('UA','Ukraine'),('UG','Uganda');
34 | insert into pfx_countries (code, title) values ('UM','United States Minor Outlying Islands'),('US','United States of America'),('UY','Uruguay'),('UZ','Uzbekistan'),('VA','Vatican City State (Holy See)');
35 | insert into pfx_countries (code, title) values ('VC','St. Vincent & the Grenadines'),('VE','Venezuela'),('VG','British Virgin Islands'),('VI','United States Virgin Islands'),('VN','Viet Nam');
36 | insert into pfx_countries (code, title) values ('VU','Vanuatu'),('WF','Wallis & Futuna Islands'),('WS','Samoa'),('YE','Yemen'),('YT','Mayotte'),('YU','Yugoslavia'),('ZA','South Africa');
37 | insert into pfx_countries (code, title) values ('ZM','Zambia'),('ZR','Zaire'),('ZW','Zimbabwe'),('ZZ','Unknown');
38 |
--------------------------------------------------------------------------------
/css/bs_cm.php:
--------------------------------------------------------------------------------
1 |
4 |
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | overflow-x: auto;
10 | padding: 0.5em;
11 | color: #333;
12 | background: #f8f8f8;
13 | -webkit-text-size-adjust: none;
14 | }
15 |
16 | .hljs-comment,
17 | .hljs-template_comment,
18 | .diff .hljs-header,
19 | .hljs-javadoc {
20 | color: #998;
21 | font-style: italic;
22 | }
23 |
24 | .hljs-keyword,
25 | .css .rule .hljs-keyword,
26 | .hljs-winutils,
27 | .javascript .hljs-title,
28 | .nginx .hljs-title,
29 | .hljs-subst,
30 | .hljs-request,
31 | .hljs-status {
32 | color: #333;
33 | font-weight: bold;
34 | }
35 |
36 | .hljs-number,
37 | .hljs-hexcolor,
38 | .ruby .hljs-constant {
39 | color: #008080;
40 | }
41 |
42 | .hljs-string,
43 | .hljs-tag .hljs-value,
44 | .hljs-phpdoc,
45 | .hljs-dartdoc,
46 | .tex .hljs-formula {
47 | color: #d14;
48 | }
49 |
50 | .hljs-title,
51 | .hljs-id,
52 | .scss .hljs-preprocessor {
53 | color: #900;
54 | font-weight: bold;
55 | }
56 |
57 | .javascript .hljs-title,
58 | .hljs-list .hljs-keyword,
59 | .hljs-subst {
60 | font-weight: normal;
61 | }
62 |
63 | .hljs-class .hljs-title,
64 | .hljs-type,
65 | .vhdl .hljs-literal,
66 | .tex .hljs-command {
67 | color: #458;
68 | font-weight: bold;
69 | }
70 |
71 | .hljs-tag,
72 | .hljs-tag .hljs-title,
73 | .hljs-rules .hljs-property,
74 | .django .hljs-tag .hljs-keyword {
75 | color: #000080;
76 | font-weight: normal;
77 | }
78 |
79 | .hljs-attribute,
80 | .hljs-variable,
81 | .lisp .hljs-body {
82 | color: #008080;
83 | }
84 |
85 | .hljs-regexp {
86 | color: #009926;
87 | }
88 |
89 | .hljs-symbol,
90 | .ruby .hljs-symbol .hljs-string,
91 | .lisp .hljs-keyword,
92 | .clojure .hljs-keyword,
93 | .scheme .hljs-keyword,
94 | .tex .hljs-special,
95 | .hljs-prompt {
96 | color: #990073;
97 | }
98 |
99 | .hljs-built_in {
100 | color: #0086b3;
101 | }
102 |
103 | .hljs-preprocessor,
104 | .hljs-pragma,
105 | .hljs-pi,
106 | .hljs-doctype,
107 | .hljs-shebang,
108 | .hljs-cdata {
109 | color: #999;
110 | font-weight: bold;
111 | }
112 |
113 | .hljs-deletion {
114 | background: #fdd;
115 | }
116 |
117 | .hljs-addition {
118 | background: #dfd;
119 | }
120 |
121 | .diff .hljs-change {
122 | background: #0086b3;
123 | }
124 |
125 | .hljs-chunk {
126 | color: #aaa;
127 | }
128 |
--------------------------------------------------------------------------------
/css/task/view.css:
--------------------------------------------------------------------------------
1 | #task-attempt input[type=submit] {
2 | width:150px;
3 | height:50px;
4 | font-size:200%;
5 | }
6 |
7 | #code-tools input {
8 | width: 105px;
9 | }
10 |
--------------------------------------------------------------------------------
/ctl/.htaccess:
--------------------------------------------------------------------------------
1 | Order deny,allow
2 | Deny from all
3 |
--------------------------------------------------------------------------------
/ctl/Login.php:
--------------------------------------------------------------------------------
1 | util->paramPost('username');
4 | $password = $ctx->util->paramPost('password');
5 | $password2 = $ctx->util->paramPost('password2');
6 | $email = $ctx->util->paramPost('email');
7 |
8 | if (!empty($username) && !empty($password) && strlen($password) > 5) {
9 | if (!empty($email) && !empty($password2)) {
10 | $res = $ctx->userService->checkRegisterData($username, $password, $password2, $email);
11 | if ($res !== null) {
12 | $ctx->util->flash("Error: $res");
13 | } else {
14 | $emailHash = $ctx->loginService->hashEmail($email);
15 | $user = $ctx->userService->register($username, "!!$emailHash", $password);
16 | if (!is_object($user)) {
17 | $ctx->util->redirect('error');
18 | return;
19 | }
20 | $ctx->loginService->login($user->username, $password);
21 | $ctx->util->flash("Thanks for registering!");
22 | $ctx->util->redirect('task_list');
23 | }
24 | } else {
25 | if ($ctx->loginService->login($username, $password)) {
26 | $ctx->util->flash("Hello, glad to see you!");
27 | $ctx->util->redirect('task_list');
28 | } else {
29 | $ctx->util->flash("Username or password is wrong?");
30 | }
31 | }
32 | }
33 |
34 | $model->logged = $ctx->auth->loggedUser() !== null;
35 | $ctx->elems->robots = 'noindex,nofollow';
36 |
37 |
--------------------------------------------------------------------------------
/ctl/Logout.php:
--------------------------------------------------------------------------------
1 | auth->logout();
4 |
5 | session_unset();
6 |
7 | $ctx->util->flash('Logout successful. See you later!');
8 | $ctx->util->redirect('main');
9 |
--------------------------------------------------------------------------------
/ctl/Main.php:
--------------------------------------------------------------------------------
1 | util->redirect(preg_replace('/index.*$/', '', $requestUri));
7 | }
8 |
9 | $model->rank = $ctx->userService->topOfWeek();
10 |
11 | $taskIds = $ctx->tasksDao->findIds('shown <> 0');
12 | $taskIds = array_slice($taskIds, sizeof($taskIds) - 7);
13 | $taskIds = implode(',', $taskIds);
14 | $model->lastTasks = $taskIds ? array_reverse($ctx->tasksDao->find("id in ($taskIds)")) : [];
15 |
16 | $model->lastForum =
17 | array_slice($ctx->forumService->recentList(), 0, 5);
18 |
19 | $ctx->elems->analytics = true;
20 |
21 | $model->logged = ($ctx->auth->loggedUser() !== null);
22 |
--------------------------------------------------------------------------------
/ctl/Wiki.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | if (!$url) {
6 | $ctx->util->changePage('wiki/index');
7 | $model->pages = $ctx->wikiDao->find();
8 | $ctx->elems->title = 'Wiki: index';
9 | $model->lastmod = '2014-01-01 00:00:00';
10 | } else {
11 | $url = $ctx->strUtils->nameToUrl($url);
12 | $wikipage = $ctx->wikiDao->findFirst("url = '$url'");
13 |
14 | if (!is_object($wikipage)) {
15 | $ctx->util->changePage('error404');
16 | return;
17 | }
18 |
19 | $model->title = $wikipage->title;
20 | $model->url = $wikipage->url;
21 | $model->text = $ctx->markDown->parse(base64_decode($wikipage->data));
22 | $model->lastmod = $wikipage->lastmod;
23 |
24 | $ctx->elems->title = 'Wiki: ' . $wikipage->title;
25 | if (strpos($model->text, '') !== false) {
26 | $ctx->elems->robots = 'noindex,nofollow';
27 | }
28 | }
29 |
30 | $ctx->miscService->headerLastModified($model->lastmod);
31 |
32 | $ctx->elems->styles[] = 'jsmonoterm';
33 | $ctx->elems->scripts[] = 'jsmonoterm';
34 | $ctx->elems->analytics = true;
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ctl/_hookBefore.php:
--------------------------------------------------------------------------------
1 | httpReferrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
5 |
--------------------------------------------------------------------------------
/ctl/api/Weekbest.php:
--------------------------------------------------------------------------------
1 | userService->topOfWeek();
4 |
5 | $res = '';
6 | foreach ($best as $entry) {
7 | $url = url('user_profile', 'param', $entry->url);
8 | $res .= "
{$entry->username} "
9 | . "{$entry->rank} {$entry->cnt} \n";
10 | }
11 |
12 | header('Cache-Control: max-age=1200');
13 | $ctx->util->plainOutput($res);
14 |
--------------------------------------------------------------------------------
/ctl/forum/Delete.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $url = $ctx->util->paramGet('param');
9 |
10 | $topic = $ctx->forumService->loadTopicByUrl($url);
11 | if (!is_object($topic)) {
12 | $ctx->util->changePage('error404');
13 | return;
14 | }
15 |
16 | $posts = $ctx->forumPostsDao->find("topicid = {$topic->id}");
17 |
18 | $ctx->forumTopicsDao->delete($topic->id);
19 |
20 | foreach ($posts as $p) {
21 | $ctx->forumPostsDao->delete($p->id);
22 | }
23 |
24 | $ctx->util->flash('Topic deleted');
25 | $ctx->util->redirect('forum_view');
26 |
--------------------------------------------------------------------------------
/ctl/forum/Edit.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | if (!empty($url) && preg_match('/[0-9A-F]{32}/i', $url)) {
6 | $id = $ctx->miscService->decryptInt($url);
7 | if ($id !== null) {
8 | $post = $ctx->forumPostsDao->read($id);
9 | }
10 | }
11 |
12 | if (empty($post)) {
13 | $ctx->util->changePage('error404');
14 | return;
15 | }
16 |
17 | $model->postText = base64_decode($post->post);
18 | $model->url = $url;
19 |
20 | $ctx->forumService->resourcesForCodeMirror();
21 |
22 | $ctx->elems->robots = 'noindex,nofollow';
23 | $ctx->elems->title = 'Editing forum post';
24 | $ctx->elems->analytics = false;
25 |
26 |
--------------------------------------------------------------------------------
/ctl/forum/Main.php:
--------------------------------------------------------------------------------
1 | forums = $ctx->forumsDao->makeLookup();
4 |
5 | foreach ($model->forums as $forum) {
6 | $forum->info = $ctx->markdown->parse(base64_decode($forum->info));
7 | }
8 |
9 | $model->topics = $ctx->forumService->recentList($model->forums);
10 |
11 | $ctx->elems->title = "Forums";
12 | $ctx->elems->description = 'Dicussion forum about solving programming problems and learning to code';
13 | $ctx->elems->analytics = true;
14 |
15 |
--------------------------------------------------------------------------------
/ctl/forum/Newtopic.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | if (empty($url) || !$ctx->miscService->validUrlParam($url)) {
6 | $url = 'general';
7 | }
8 |
9 | $forum = $ctx->forumsDao->findFirst("url = '$url'");
10 |
11 | if (!is_object($forum)) {
12 | $ctx->util->changePage('error404');
13 | return;
14 | }
15 |
16 | $model->forum = $forum;
17 | $model->newTopic = true;
18 |
19 | $ctx->forumService->resourcesForCodeMirror();
20 |
21 | $ctx->elems->robots = 'noindex,nofollow';
22 | $ctx->elems->title = 'Create forum topic';
23 | $ctx->elems->analytics = false;
24 |
25 |
--------------------------------------------------------------------------------
/ctl/forum/Post.php:
--------------------------------------------------------------------------------
1 | util->paramPost('url');
4 | $topicTitle = $ctx->util->paramPost('topictitle');
5 | $text = $ctx->util->paramPost('text');
6 | $taskId = $ctx->util->paramPost('task');
7 | $userId = $ctx->auth->loggedUser();
8 |
9 | if ((empty($url) && empty($topicTitle)) || empty($text) || strlen($text) < 20 || strlen($text) > 5000) {
10 | $ctx->util->changePage('message');
11 | $model->msg = 'Message post should have from 20 to 5000 characters length!';
12 | return;
13 | }
14 |
15 | if (!$ctx->miscService->validUrlParam($url) || !$userId || !$ctx->userService->forumAllowed()) {
16 | $ctx->util->redirect('error');
17 | return;
18 | }
19 |
20 | if (!empty($topicTitle)) {
21 | $topicTitle = $ctx->forumService->stripTopicTitle($topicTitle);
22 | if (strlen($topicTitle) < 10 || strlen($topicTitle) > 100) {
23 | $ctx->util->changePage('message');
24 | $model->msg = 'Topic title should have from 10 to 100 characters length!';
25 | return;
26 | }
27 | if (!empty($taskId)) {
28 | if (!preg_match('/\d+/', $taskId)) {
29 | $ctx->util->changePage('message');
30 | $model->msg = 'Task number for private forum seems to be incorrect!';
31 | return;
32 | }
33 | $taskId = intval($taskId);
34 | if (!$ctx->auth->admin() && !$ctx->userService->haveSolved($userId, $taskId)) {
35 | $ctx->util->changePage('message');
36 | $model->msg = 'You can not create private forum for task which you have not solved yet!';
37 | return;
38 | }
39 | } else {
40 | $taskId = 0;
41 | }
42 |
43 | $forum = $ctx->forumsDao->findFirst("url = '$url'");
44 | if (is_object($forum)) {
45 | $topic = new \stdClass();
46 | $topic->forumid = $forum->id;
47 | $topic->userid = $userId;
48 | $topic->taskId = $taskId;
49 | $topic->title = $topicTitle;
50 | $topic->url = md5($topicTitle . $forum->title . rand());
51 | $topic->created = $ctx->miscService->curTimeStr();
52 | $url = $topic->url;
53 | $ctx->forumTopicsDao->save($topic);
54 | } else {
55 | $url = '';
56 | }
57 | }
58 |
59 | $topic = $ctx->forumTopicsDao->findFirst("url = '$url'");
60 |
61 | if (!is_object($topic)) {
62 | $ctx->util->changePage('error404');
63 | return;
64 | }
65 |
66 | $post = new \stdClass();
67 | $post->userid = $userId;
68 | $post->topicid = $topic->id;
69 | $post->post = base64_encode($text);
70 | $post->created = $ctx->miscService->curTimeStr();
71 | $postId = $ctx->forumPostsDao->save($post);
72 |
73 | $topic->posts += 1;
74 | $topic->lastpost = $ctx->miscService->curTimeStr();
75 | $topic->lastpostid = $postId;
76 | $ctx->forumTopicsDao->save($topic);
77 |
78 | $ctx->util->redirect(url('forum_topic', 'param', $url));
79 |
80 |
--------------------------------------------------------------------------------
/ctl/forum/Rename.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $newName = $ctx->util->paramPost('newname');
9 | $url = $ctx->util->paramPost('url');
10 |
11 | $newName = trim($newName);
12 | $topic = $ctx->forumService->loadTopicByUrl($url);
13 |
14 | if (!is_object($topic) || strlen($newName) < 3) {
15 | $ctx->util->changePage('error404');
16 | return;
17 | }
18 |
19 | if ($newName[0] != '/') {
20 | $newName = $ctx->forumService->stripTopicTitle($newName);
21 | if (!is_object($topic) || strlen($newName) < 5) {
22 | $ctx->util->flash('Bad title?');
23 | $ctx->util->redirect('error');
24 | return;
25 | }
26 | $topic->title = $newName;
27 | } else {
28 | $forumUrl = substr($newName, 1);
29 | $forum = $ctx->forumService->loadForumByUrl($forumUrl);
30 | if (!is_object($forum)) {
31 | $ctx->util->flash('No such forum?');
32 | $ctx->util->redirect('error');
33 | return;
34 | }
35 | $topic->forumid = $forum->id;
36 | }
37 |
38 | $ctx->forumTopicsDao->save($topic);
39 | $ctx->util->redirect(url('forum_topic', 'param', $url));
40 |
41 |
--------------------------------------------------------------------------------
/ctl/forum/Topic.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | if (empty($url) || !$ctx->miscService->validUrlParam($url)) {
6 | $ctx->util->changePage('error404');
7 | return;
8 | }
9 |
10 | $topic = $ctx->forumTopicsDao->findFirst("url = '$url'");
11 |
12 | if (!is_object($topic)) {
13 | $ctx->util->changePage('error404');
14 | return;
15 | }
16 |
17 | if ($topic->taskid) {
18 | $model->forTask = $ctx->tasksDao->read($topic->taskid);
19 | $restrict = $ctx->forumService->privateTopicRestriction($topic->taskid);
20 | if ($restrict) {
21 | $ctx->util->changePage('forum_noaccess');
22 | $ctx->elems->robots = 'noindex,nofollow';
23 | $ctx->elems->title = 'Private Forum';
24 | $ctx->elems->analytics = false;
25 | return;
26 | }
27 | }
28 |
29 | $model->topic = $topic;
30 | $model->forum = $ctx->forumsDao->read($topic->forumid);
31 | $model->posts = $ctx->forumService->loadPosts($topic);
32 | $model->posts[count($model->posts) - 1]->lastPost = true;
33 |
34 | $model->showForm = $ctx->userService->forumAllowed();
35 | if ($model->showForm) {
36 | $ctx->forumService->resourcesForCodeMirror();
37 | }
38 |
39 | $ctx->elems->title = "{$model->forum->title}: {$topic->title}";
40 | $ctx->elems->analytics = true;
41 |
42 |
--------------------------------------------------------------------------------
/ctl/forum/Update.php:
--------------------------------------------------------------------------------
1 | util->paramPost('url');
4 | $text = $ctx->util->paramPost('text');
5 |
6 | if (!empty($id) && !empty($text) && preg_match('/[0-9A-F]{32}/i', $id)) {
7 | $id = $ctx->miscService->decryptInt($id);
8 | if ($id !== null) {
9 | $post = $ctx->forumPostsDao->read($id);
10 | }
11 | }
12 |
13 | if (empty($post)) {
14 | $ctx->util->changePage('error404');
15 | return;
16 | }
17 |
18 | $post->post = base64_encode($text);
19 | $ctx->forumPostsDao->save($post);
20 |
21 | $topic = $ctx->forumTopicsDao->read($post->topicid);
22 |
23 | $ctx->util->redirect(url('forum_topic', 'param', $topic->url));
24 |
25 |
--------------------------------------------------------------------------------
/ctl/forum/View.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | if (empty($url) || !$ctx->miscService->validUrlParam($url)) {
6 | $forum = new \stdClass();
7 | $forum->id = null;
8 | $forum->info = '';
9 | } else {
10 | $forum = $ctx->forumsDao->findFirst("url = '$url'");
11 | }
12 |
13 | if (!is_object($forum)) {
14 | $ctx->util->changePage('error404');
15 | return;
16 | }
17 |
18 | $model->topics = $ctx->forumService->loadTopics($forum->id);
19 |
20 | foreach ($model->topics as $topic) {
21 | if ($topic->taskid) {
22 | $topic->title = "[Task#{$topic->taskid}] {$topic->title}";
23 | }
24 | }
25 |
26 | if (!empty($forum->info)) {
27 | $forum->info = $ctx->markdown->parse(base64_decode($forum->info));
28 | }
29 |
30 | $model->forum = $forum;
31 |
32 | $model->otherForums = !empty($url) ? $ctx->forumsDao->find("url != '$url'") : array();
33 |
34 | $model->showCreateLink = $ctx->userService->forumAllowed();
35 |
36 | $ctx->elems->title = 'Forum';
37 | if (!empty($forum->title)) {
38 | $ctx->elems->title .= ": {$forum->title}";
39 | }
40 | $ctx->elems->analytics = true;
41 |
42 |
--------------------------------------------------------------------------------
/ctl/mess/Hall.php:
--------------------------------------------------------------------------------
1 | records = $ctx->chatViewDao->find();
4 |
5 | $oldestTime = time() - 86400;
6 | for ($i = 0; $i < count($model->records); $i++) {
7 | $rec = $model->records[$i];
8 | $time = strtotime($rec->created);
9 | if ($time < $oldestTime) {
10 | array_splice($model->records, $i);
11 | break;
12 | }
13 | $rec->message = $ctx->markdown->parse(base64_decode($rec->message));
14 | $rec->created = date('H:i:s', $time);
15 | $rec->rank = $ctx->userService->rank($rec->solved, $rec->username);
16 | }
17 |
18 | $model->stats = $ctx->userTasksDao->solvingStats(date('Y-m-d', time() - 86400 * 15));
19 | if ($ctx->auth->admin()) {
20 | $statsAvg = 0;
21 | for ($i = 1; $i < count($model->stats); $i++) {
22 | $statsAvg += $model->stats[$i]->cnt;
23 | }
24 | $model->statsAvg = number_format($statsAvg / (count($model->stats) - 1), 1);
25 | }
26 |
27 | $model->rights = $ctx->userService->messAllowed();
28 |
29 | $ctx->elems->robots = 'noindex,nofollow';
30 | $ctx->elems->title = 'Mess Hall';
31 | $ctx->elems->analytics = true;
32 |
33 |
--------------------------------------------------------------------------------
/ctl/task/Attempt2.php:
--------------------------------------------------------------------------------
1 | auth->user()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $ctx->util->plainOutput('');
9 |
10 | $inputPlain = file_get_contents('php://input');
11 | $input = json_decode($inputPlain);
12 |
13 | $taskid = $input->taskid;
14 | $answer = $input->answer;
15 | $solution = $input->solution;
16 | $lang = $input->lang;
17 | if ($input->b64enc ?? 0) {
18 | if ($solution[0] == '-') {
19 | $solution = strrev(substr($solution, 1));
20 | }
21 | $solution = str_replace(array('.','_','-'), array('+','/','='), $solution);
22 | $solution = base64_decode($solution);
23 | }
24 |
25 | if (!is_numeric($taskid) || !$solution || !$answer) {
26 | echo json_encode(['msg'=>'Insufficient data A', 'data'=>$inputPlain]);
27 | return;
28 | }
29 |
30 | $lastSolved = $ctx->util->sessionGet('lastSolved');
31 | if ($lastSolved) {
32 | $ctx->util->sessionDel('lastSolved');
33 | $last = array_map('intval', explode(' ', $lastSolved));
34 | $secRem = ($last[0] == $taskid ? $last[2] : max($last[2], $last[1])) - time();
35 | if ($secRem > 0) {
36 | echo json_encode(['msg'=>"You could not submit new tasks for $secRem seconds more"]);
37 | return;
38 | }
39 | }
40 |
41 | $languages = $ctx->langService->languagesArray();
42 | $lang = isset($languages[$lang]) ? $languages[$lang] : "";
43 |
44 | $task = $ctx->tasksDao->findFirst("id = $taskid");
45 |
46 | if (!is_object($task)) {
47 | echo json_encode(['msg'=>'Unknown task']);
48 | return;
49 | }
50 |
51 | $userid = $ctx->auth->loggedUser();
52 | $userData = $ctx->userDataDao->findFirst("userid = $userid");
53 |
54 | if ($ctx->cheatService->isSuspended($userid)) {
55 | echo json_encode(['msg'=>'Submission not accepted from this account']);
56 | return;
57 | }
58 |
59 | $ctx->util->sessionPut('last_subm', time());
60 |
61 | $res = $ctx->taskService->processSolution($task, $userid, $answer, $solution, $lang);
62 | $json = new \stdClass();
63 | $json->solved = $res[0];
64 | $json->gainedPoints = number_format($res[1], 2);
65 | $json->userPoints = number_format($res[2], 2);
66 | $json->task = $task;
67 |
68 | if ($res[1] > 0 && !$ctx->elems->conf->calcPointsSecret) {
69 | $ctx->miscService->calcPoints();
70 | }
71 |
72 | $rndPrimes = array(13, 17, 19, 23, 29, 31, 37);
73 | $json->userRnd = $rndPrimes[$userid % count($rndPrimes)];
74 | $json->numSolved = $userData->solved;
75 |
76 | $expectedAnswer = $ctx->taskService->deleteAnswer($taskid);
77 | if (strlen($expectedAnswer) > 2) {
78 | $eaPrefix = substr($expectedAnswer, 0, 2);
79 | if ($eaPrefix === "' " || $eaPrefix == '. ') {
80 | $expectedAnswer = substr($expectedAnswer, 2);
81 | }
82 | }
83 |
84 | if ($json->solved) {
85 | if ($ctx->challengeService->challengeExists($taskid)) {
86 | $json->challengeResult = explode(' ', $expectedAnswer, 3);
87 | }
88 | } else {
89 | $json->answer = $expectedAnswer;
90 | $json->submittedAnswer = base64_encode($answer);
91 | $json->inputData = $ctx->taskService->deleteInputData($taskid);
92 | }
93 |
94 | $url = url('task_view', 'param', $task->url);
95 | $msg = $json->solved
96 | ? "I'm proud to tell I've just solved [{$task->title}]($url)!"
97 | : "I'm sorry to say I've failed [{$task->title}]($url)... :(";
98 | $ctx->miscService->postToMessHall($userid, $msg);
99 | $ctx->miscService->logAction($userid, ($json->solved ? 'solved' : 'failed') . " {$task->id}");
100 |
101 | if ($json->solved && $json->gainedPoints > 0) {
102 | $nowSolved = $userData->solved + 1; //we haven't reloaded UD after update
103 | $json->numSolved = $nowSolved;
104 | $rank = $ctx->userService->rankAsNumber($nowSolved);
105 | $rankOld = $ctx->userService->rankAsNumber($userData->solved);
106 | if ($rank != $rankOld) {
107 | $rank = $ctx->userService->rank($nowSolved);
108 | $ctx->miscService->postToMessHall($userid,
109 | "I'm excited to announce I've achieved "
110 | . "$rank rank!!! ");
111 | }
112 | }
113 |
114 | echo json_encode($json);
115 |
--------------------------------------------------------------------------------
/ctl/task/Edit.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $id = $ctx->util->paramGet('id');
9 | $vol = $ctx->util->paramGet('vol');
10 |
11 | if (is_numeric($id)) {
12 | $model->task = $ctx->tasksDao->read($id);
13 | $taskdata = $ctx->taskDataDao->makeLookup('type', "taskid = $id");
14 | $model->task->title = htmlentities($model->task->title);
15 | $model->task->text = base64_decode($taskdata['text']->data);
16 | $model->task->checker = base64_decode($taskdata['checker']->data);
17 | } else {
18 | $model->task = new stdClass();
19 | $model->task->id = null;
20 | $model->task->title = '';
21 | $model->task->url = '';
22 | $model->task->author = '';
23 | $model->task->volumeid = '';
24 | $model->task->shown = 0;
25 | $model->task->text = "(problem statement in markdown format, please)";
26 | $model->task->checker = "";
27 | }
28 |
29 |
30 | array_push($ctx->elems->styles, 'codemirror');
31 | array_push($ctx->elems->scripts, '_cm/codemirror');
32 | array_push($ctx->elems->scripts, '_cm/clike');
33 | array_push($ctx->elems->scripts, '_cm/php');
34 | array_push($ctx->elems->scripts, '_cm/markdown');
35 | array_push($ctx->elems->scripts, '_cm/xml');
36 | array_push($ctx->elems->scripts, '_cm/matchbrackets');
37 |
--------------------------------------------------------------------------------
/ctl/task/List.php:
--------------------------------------------------------------------------------
1 | title = 'Problems';
4 |
5 | $model->addingAllowed = $ctx->auth->admin();
6 | $model->isUser = $ctx->auth->user();
7 |
8 | $param = $ctx->util->paramGet('param');
9 | if (!$ctx->miscService->validUrlParam($param)) {
10 | $param = '';
11 | }
12 | $sort = $ctx->util->paramGet('sort');
13 | if (!in_array($sort, array('tre1', 'num1', 'id1', 'num0', 'id0'))) {
14 | if ($ctx->auth->loggedUser()) {
15 | $sort = $ctx->util->sessionGet('task-list-sort');
16 | }
17 | $sort = empty($sort) ? $ctx->elems->conf->defTaskSort : $sort;
18 | } else {
19 | if ($ctx->auth->loggedUser()) {
20 | $ctx->util->sessionPut('task-list-sort', $sort);
21 | }
22 | }
23 | $model->sort = $sort;
24 | $sortlen = strlen($sort) - 1;
25 | $sort = array(substr($sort, 0, $sortlen), substr($sort, $sortlen));
26 |
27 | $tasks = null;
28 | if (!empty($param)) {
29 | $tag = $ctx->tagsDao->findFirst("title = '$param'");
30 | if (is_object($tag)) {
31 | $tasks = $ctx->taskService->loadTasks($tag->id);
32 | $model->filterTag = $tag->title;
33 | $model->volume = $ctx->elems->conf->taskVolumes[$tag->title] ?? null;
34 | } else {
35 | $ctx->util->flash("No such tag");
36 | $ctx->util->redirect('task_list');
37 | return;
38 | }
39 | }
40 | if (empty($tasks)) {
41 | $tasks = $ctx->taskService->loadTasks(null);
42 | }
43 | $model->c1ids = $ctx->taskTagsDao->makeLookup('taskid',
44 | "tagid = (select id from {$ctx->tagsDao->getTable()} where title = 'c-1')");
45 | if ($sort[0] == 'id') {
46 | usort($tasks, function($a, $b) {
47 | return $a->id - $b->id;
48 | });
49 | } elseif ($sort[0] == 'tre') {
50 | $sortCnt = $ctx->tasksDao->getCount() + 1;
51 | usort($tasks, function($a, $b) use($sortCnt) {
52 | $av = ($sortCnt - $a->id) / ($a->solved + 1);
53 | $bv = ($sortCnt - $b->id) / ($b->solved + 1);
54 | return ($av > $bv) - ($av < $bv);
55 | });
56 | }
57 |
58 | if ($model->isUser) {
59 | $userid = $ctx->auth->loggedUser();
60 | $failedTasks = $ctx->userTasksDao->makeLookup('taskid', "userid = $userid and solved < 0 and variant = 1");
61 | $userTasks = $ctx->userTasksDao->makeLookup('taskid', "userid = $userid and variant = 0");
62 | foreach ($failedTasks as $taskId => $taskRecord) {
63 | if (!isset($userTasks[$taskId])) {
64 | $userTasks[$taskId] = $taskRecord;
65 | }
66 | }
67 | $starred = $ctx->miscService->getTaggedValue("star.$userid");
68 | if ($starred) {
69 | $starred = array_fill_keys(explode(',', $starred), 1);
70 | foreach ($tasks as &$task)
71 | if (isset($starred['' . $task->id]))
72 | $task->starred = 1;
73 | if ($sort[0] == 'tre') {
74 | $tasks1 = [];
75 | $tasks2 = [];
76 | foreach ($tasks as &$task) {
77 | if ($task->starred)
78 | $tasks1[] = $task;
79 | else
80 | $tasks2[] = $task;
81 | }
82 | $tasks = array_merge($tasks1, $tasks2);
83 | }
84 | }
85 | }
86 |
87 | $translations = $ctx->miscService->getTaggedValues('tran-');
88 |
89 | $states = array(-1 => 'tried', 0 => 'waiting', 1 => 'solved');
90 |
91 | $headPart = array();
92 | $tailPart = array();
93 |
94 | foreach ($tasks as $task) {
95 | $task->solved = $ctx->strUtils->zeroDash($task->solved);
96 | if (!$task->shown) {
97 | if (!$model->addingAllowed) {
98 | continue;
99 | }
100 | $task->solved = 'hid';
101 | }
102 | $task->cost = number_format($task->cost, 2);
103 | $task->shortUrl = $task->url;
104 | $task->url = url('task_view', 'param', $task->url);
105 | if ($model->addingAllowed) {
106 | $task->editurl = url('task_edit', 'id', $task->id);
107 | }
108 | if ($model->isUser && isset($userTasks[$task->id])) {
109 | $task->state = $states[$userTasks[$task->id]->solved];
110 | } else {
111 | $task->state = '';
112 | }
113 | if ($task->state == 'solved' && $sort[1]) {
114 | $tailPart[] = $task;
115 | } else {
116 | $headPart[] = $task;
117 | }
118 | if (isset($translations['tran-' . $task->id])) {
119 | $tongues = explode(' ', $translations['tran-' . $task->id]);
120 | foreach ($tongues as $i => $tongue) {
121 | $urlLocalised = "{$task->url}--$tongue";
122 | $localeTitle = $ctx->localeService->LOCALES_ARRAY[$tongue];
123 | $tongueUpper = strtoupper($tongue);
124 | $tongues[$i] = "$tongueUpper ";
125 | }
126 | $task->translations = implode(' ', $tongues);
127 | } else {
128 | $task->translations = '';
129 | }
130 | }
131 |
132 | $model->tasks = array_merge($headPart, $tailPart);
133 |
134 | $ctx->elems->title = $model->title;
135 | $ctx->elems->description = 'List of programming problems and exercises from beginner to advanced level';
136 | $ctx->elems->analytics = true;
137 |
--------------------------------------------------------------------------------
/ctl/task/Preparedata.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | $userid = $ctx->auth->loggedUser();
6 |
7 | if (!$userid || !is_numeric($taskid)) {
8 | $ctx->util->changePage('error404');
9 | return;
10 | }
11 |
12 | $data = $ctx->taskService->prepareData($taskid);
13 |
14 | $ctx->util->plainOutput($data);
15 |
--------------------------------------------------------------------------------
/ctl/task/Save.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->redirect('task_list');
5 | return;
6 | }
7 |
8 | $taskid = $ctx->util->paramPost('id');
9 |
10 | $task = null;
11 | if (is_numeric($taskid)) {
12 | $task = $ctx->tasksDao->read($taskid);
13 | }
14 |
15 | $justCreated = false;
16 | if (!is_object($task)) {
17 | $taskid = null;
18 | $task = new stdClass();
19 | $justCreated = true;
20 | }
21 |
22 | $task->id = $taskid;
23 | $task->title = $ctx->util->paramPost('title');
24 | $task->url = $ctx->util->paramPost('url');
25 | $task->author = $ctx->util->paramPost('author');
26 | $task->lastmod = date('Y-m-d');
27 | $task->shown = $ctx->util->paramPost('shown') ? 1 : 0;
28 | $statement = $ctx->util->paramPost('statement');
29 | $statement = $ctx->util->sillyDecode($statement);
30 | $checker = $ctx->util->paramPost('checker');
31 | $checker = $ctx->util->sillyDecode($checker);
32 |
33 | if (empty($task->id)) {
34 | unset($task->id);
35 | }
36 | if (empty($task->author)) {
37 | unset($task->author);
38 | }
39 | if (empty($task->volumeid)) {
40 | unset($task->volumeid);
41 | }
42 |
43 | if (!$task->title || !$statement || !$checker) {
44 | $ctx->util->changePage('message');
45 | $model->msg = 'Insufficient data';
46 | return;
47 | }
48 |
49 | $taskid = $ctx->tasksDao->save($task);
50 |
51 | $data = $ctx->taskDataDao->findFirst("taskid = $taskid and type = 'text'");
52 | if (!is_object($data)) {
53 | $data = new stdClass();
54 | $data->taskid = $taskid;
55 | $data->type = 'text';
56 | }
57 | $data->data = base64_encode($statement);
58 | $ctx->taskDataDao->save($data);
59 |
60 | $data = $ctx->taskDataDao->findFirst("taskid = $taskid and type = 'checker'");
61 | if (!is_object($data)) {
62 | $data = new stdClass();
63 | $data->taskid = $taskid;
64 | $data->type = 'checker';
65 | }
66 | $data->data = base64_encode($checker);
67 | $ctx->taskDataDao->save($data);
68 |
69 | if ($justCreated) {
70 | $tagObject = $ctx->tagsDao->findFirst("title = 'unlabeled'");
71 | $assignment = new \stdClass();
72 | $assignment->tagid = $tagObject->id;
73 | $assignment->taskid = $taskid;
74 | $ctx->taskTagsDao->save($assignment);
75 | }
76 |
77 | $ctx->util->redirect(url('task_view', 'param', $task->url));
78 |
--------------------------------------------------------------------------------
/ctl/task/Solution.php:
--------------------------------------------------------------------------------
1 | util->paramGet('task');
4 | $userurl = $ctx->util->paramGet('user');
5 | $language = $ctx->util->paramGet('lang');
6 | $key = $ctx->util->paramGet('key');
7 |
8 | $langArray = $ctx->langService->languagesArray();
9 |
10 | if (!$ctx->miscService->validUrlParams($taskurl, $userurl) || !in_array($language, $langArray)) {
11 | $ctx->util->changePage('error404');
12 | return;
13 | }
14 |
15 | $currentUserId = $ctx->auth->loggedUser();
16 |
17 | if (!$currentUserId && !$key) {
18 | $ctx->util->changePage('message');
19 | $model->msg = "Excuse us, but you need to be logged in and to solve the task to view other's solution!";
20 | return;
21 | }
22 |
23 | $ts = $key ? substr($key, 24) : base_convert(time(), 10, 16);
24 | $toHash = "{$ctx->elems->conf->viewSolutionSecret}+$ts+$taskurl+$userurl+$language";
25 | $h = substr(hash('sha256', $toHash), 0, 24);
26 | if ($key) {
27 | $tsd = base_convert($ts, 16, 10);
28 | if ($h . $ts != $key || $tsd < time() - 86400*7) {
29 | $ctx->util->changePage('message');
30 | $model->msg = "Link is either broken or expired...";
31 | return;
32 | }
33 | }
34 |
35 | $task = $ctx->tasksDao->findFirst("url = '$taskurl'");
36 | $user = $ctx->usersDao->findFirst("url = '$userurl'");
37 |
38 | if (!is_object($task) || !is_object($user)) {
39 | $ctx->util->changePage('error404');
40 | return;
41 | }
42 |
43 | $model->key = ($currentUserId == $user->id) ? $h . $ts : '';
44 |
45 | if ($ctx->util->paramGet('plain') && $currentUserId == $user->id) {
46 | try {
47 | list($usertask, $solution) = $ctx->taskService->loadSolution($task->id, $user->id, $language);
48 | $solution = $solution->solution;
49 | } catch (\Exception $e) {
50 | $solution = 'Code loading failed :(';
51 | }
52 | $ctx->util->plainOutput($solution);
53 | return;
54 | }
55 |
56 | if ($ctx->challengeService->challengeExists($task->id)
57 | && ($currentUserId != $user->id && !$ctx->auth->admin())) {
58 | $ctx->util->redirect(url('task_chlng_stats', 'param', $task->url));
59 | $ctx->util->flash("You can't see solutions for Challenges!");
60 | return;
61 | }
62 |
63 | $model->solution = $ctx->taskService->viewSolution($task, $user, $language, $key !== null);
64 |
65 | $model->changeLangAllowed = ($currentUserId === $user->id || $ctx->auth->admin());
66 |
67 | $model->highlight = (!empty($model->solution->language) && $model->solution->language != 'other')
68 | ? strtolower($model->solution->language) : '';
69 |
70 | if ($model->changeLangAllowed && !$model->solution->error) {
71 | $model->language = strtolower($model->solution->language);
72 | $model->languages = $ctx->langService->languagesArray();
73 | }
74 |
75 | $ctx->elems->styles[] = 'jqui';
76 | $ctx->elems->styles[] = 'highlight';
77 | $ctx->elems->scripts[] = 'jqui';
78 | $ctx->elems->scripts[] = 'highlight';
79 |
80 | $ctx->elems->robots = 'noindex,follow';
81 | $ctx->elems->title = 'View solution';
82 | $ctx->elems->analytics = true;
83 |
84 |
--------------------------------------------------------------------------------
/ctl/task/Solvers.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 | $language = $ctx->util->paramGet('lang');
5 |
6 | if (!$ctx->miscService->validUrlParam($taskurl)
7 | || (!empty($language) && !array_key_exists($language, $ctx->elems->conf->languages))) {
8 | $ctx->util->changePage('error404');
9 | return;
10 | }
11 |
12 | $task = $ctx->tasksDao->findFirst("url = '$taskurl'");
13 |
14 | if (!is_object($task)) {
15 | $ctx->util->flash($taskurl);
16 | $ctx->util->changePage('error404');
17 | return;
18 | }
19 |
20 | if ($ctx->challengeService->challengeExists($task->id)) {
21 | $ctx->util->redirect(url('task_chlng_stats', 'param', $task->url));
22 | return;
23 | }
24 |
25 | $criteria = "solved = 1 and taskid = {$task->id}";
26 | if (!empty($language)) {
27 | $criteria .= " and language = '$language'";
28 | }
29 | $ids = $ctx->userTasksDao->solvers($criteria, !$ctx->util->paramGet('withblanks'));
30 | shuffle($ids);
31 | if (count($ids) > 15) {
32 | $limit = $ctx->util->paramGet('limit');
33 | $ids = array_slice($ids, 0, !!$limit ? min(100, intval($limit)) : 15);
34 | }
35 |
36 | $res = array();
37 | foreach ($ids as $utid) {
38 | $ut = $ctx->userTasksDao->read($utid);
39 | $user = $ctx->usersDao->read($ut->userid);
40 | $entry = new stdClass();
41 | $entry->url = $user->url;
42 | $entry->username = $user->username;
43 | $entry->language = $ut->language;
44 | $res[] = $entry;
45 | }
46 |
47 | $model->task = $task;
48 | $model->users = $res;
49 |
50 | $loadNotes = true;
51 | if (!$ctx->taskService->isAdminOrAuthor($task)) {
52 | if (!$ctx->auth->loggedUser()) {
53 | $loadNotes = false;
54 | } else {
55 | $usertask = $ctx->userTasksDao->findFirst("solved = 1 and taskid = {$task->id} and userid = " . $ctx->auth->loggedUser());
56 | $loadNotes = is_object($usertask);
57 | }
58 | }
59 |
60 | if ($loadNotes) {
61 | $model->notes = $model->notes = $ctx->taskService->loadNotes($task->id);
62 | } else {
63 | $model->notes = 'You should solve the problem to see these hints!';
64 | }
65 |
66 | $model->language = $language;
67 | $model->languages = $ctx->langService->languagesArray();
68 |
69 | $ctx->elems->robots = 'noindex,nofollow';
70 | $ctx->elems->title = 'Solution list';
71 | $ctx->elems->analytics = true;
72 |
73 |
--------------------------------------------------------------------------------
/ctl/task/Star.php:
--------------------------------------------------------------------------------
1 | auth->user()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $ctx->util->plainOutput('');
9 |
10 | $userid = $ctx->auth->loggedUser();
11 | $taskid = $ctx->util->paramPost('task');
12 | $star = $ctx->util->paramPost('star');
13 |
14 | if (!is_numeric($taskid) || !in_array($star, ['0','1'], true)) {
15 | echo "badparams";
16 | return;
17 | }
18 |
19 | $tag = "star.$userid";
20 | $starred = $ctx->miscService->getTaggedValue($tag);
21 | echo "already starred: $starred\n";
22 | $starred = $starred ? explode(',', $starred) : [];
23 | $exists = array_search($taskid, $starred);
24 | if ($star) {
25 | if ($exists !== false) return;
26 | $starred[] = $taskid;
27 | echo "added star\n";
28 | } else {
29 | if ($exists === false) return;
30 | array_splice($starred, $exists, 1);
31 | echo "removed star\n";
32 | }
33 | echo "remaining starred: " . json_encode($starred) . "\n";
34 | $ctx->miscService->setTaggedValue($tag,
35 | $starred ? implode(',', $starred) : null);
36 |
--------------------------------------------------------------------------------
/ctl/task/Success.php:
--------------------------------------------------------------------------------
1 | auth->user()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $inputObj = base64_decode($ctx->util->paramPost('obj'));
9 | $input = json_decode($inputObj);
10 |
11 | $model->solved = $input->solved;
12 | $model->gainedPoints = $input->gainedPoints;
13 | $model->userPoints = $input->userPoints;
14 | $model->task = $input->task;
15 | $taskid = $model->task->id;
16 |
17 | $userid = $ctx->auth->loggedUser();
18 | $userData = $ctx->userDataDao->findFirst("userid = $userid");
19 |
20 | $rndPrimes = array(13, 17, 19, 23, 29, 31, 37);
21 | $model->userRnd = $rndPrimes[$userid % count($rndPrimes)];
22 | $model->numSolved = $userData->solved;
23 |
24 |
25 | $model->challengeResult = $input->challengeResult ?? null;
26 |
27 | $model->notes = $ctx->taskService->loadNotes($taskid);
28 |
29 | $model->nextTasks = $ctx->tasksDao->find(
30 | "solved < {$model->task->solved} order by solved desc", 5);
31 | if (count($model->nextTasks) > 3) {
32 | $model->nextTasks = array_slice($model->nextTasks, rand(0, 2), 3);
33 | }
34 | $recom = $ctx->miscService->getTaggedValue("recom-$taskid");
35 | if ($recom) {
36 | $recom = str_replace(' ', ',', $recom);
37 | $recomTasks = $ctx->tasksDao->find("id in ($recom)");
38 | array_splice($model->nextTasks, 0, 0, $recomTasks);
39 | }
40 |
41 | $ctx->elems->scripts[] = 'task/attempt';
42 |
--------------------------------------------------------------------------------
/ctl/task/Testchecker.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $code = file_get_contents("php://input");
9 |
10 | echo $ctx->taskService->testChecker($code);
11 |
12 | $ctx->util->changePage(null);
13 |
--------------------------------------------------------------------------------
/ctl/task/Text.php:
--------------------------------------------------------------------------------
1 | auth->loggedUser()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $url = $ctx->util->paramGet('param');
9 | if (!$ctx->miscService->validUrlParam($url)) {
10 | $ctx->util->changePage('error404');
11 | return;
12 | }
13 |
14 | $task = $ctx->tasksDao->findFirst("url = '$url'");
15 | if (!is_object($task)) {
16 | $ctx->util->changePage('error404');
17 | return;
18 | }
19 |
20 | $taskdata = $ctx->taskDataDao->findFirst("taskid = {$task->id} and type = 'text'");
21 |
22 | $ctx->util->plainOutput(base64_decode($taskdata->data));
23 |
--------------------------------------------------------------------------------
/ctl/task/View.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 |
5 | if ($url == null || !$ctx->miscService->validUrlParam($url)) {
6 | $ctx->util->changePage('error404');
7 | return;
8 | }
9 |
10 | list($url, $locale) = $ctx->localeService->parseLocale($url);
11 |
12 | $model->task = $ctx->tasksDao->findFirst("url = '$url'");
13 |
14 | if (!is_object($model->task)) {
15 | $ctx->util->changePage('error404');
16 | return;
17 | }
18 |
19 | $model->tags = $ctx->taskService->tagNamesForTask($model->task->id);
20 |
21 | $userid = $ctx->auth->loggedUser();
22 |
23 | $model->task->statement = $ctx->taskService->loadStatement($model->task->id, $locale);
24 |
25 | if (empty($model->task->statement)) {
26 | $ctx->util->changePage('error404');
27 | return;
28 | }
29 |
30 | $model->textDirection = $ctx->localeService->direction($locale);
31 |
32 | $alternativeLocales = $ctx->localeService->availableTaskLocales($model->task->id);
33 | $model->task->locales = empty($locale) ? $alternativeLocales : array('en' => 'English');
34 |
35 | if (!empty($alternativeLocales)) {
36 | $ctx->elems->locales = array('en' => $ctx->util->fullUrl(
37 | url('task_view', 'param', $model->task->url)));
38 | foreach ($alternativeLocales as $localeCode => $localeName) {
39 | $ctx->elems->locales[$localeCode] = $ctx->util->fullUrl(
40 | url('task_view', 'param', $model->task->url . "--$localeCode"));
41 | }
42 | }
43 |
44 | if ($ctx->auth->user()) {
45 | $user = $ctx->usersDao->findFirst("id = $userid");
46 | $userdata = $ctx->userdataDao->findFirst("userid = $userid");
47 | $usertasks = $ctx->userTasksDao->find("taskid = {$model->task->id} and userid = $userid");
48 | $model->suspended = $ctx->cheatService->isSuspended($userid);
49 | $model->codes = array();
50 | foreach ($usertasks as $ut) {
51 | $model->codes[$ut->language] = url('task_solution', 'user', $user->url, 'task', $model->task->url, 'lang', urlencode($ut->language));
52 | }
53 |
54 | $model->languages = $ctx->langService->languagesArray();
55 |
56 | if ($model->task->author == $user->url) {
57 | $model->checkerCode = str_replace('taskService->loadChecker($model->task->id));
58 | }
59 |
60 | $starred = $ctx->miscService->getTaggedValue("star.{$user->id}");
61 | $model->starred = $starred
62 | ? in_array($model->task->id, explode(',', $starred)) : false;
63 |
64 | $ctx->elems->scripts[] = 'task/_view';
65 | $ctx->elems->scripts[] = '_ace/ace';
66 | $ctx->elems->scripts[] = '_sql/sql-wasm';
67 | }
68 |
69 | if (!$userid) {
70 | $ctx->miscService->headerLastModified($model->task->lastmod);
71 | }
72 |
73 | $ctx->elems->title = $model->task->title;
74 |
75 | $model->challenge = $ctx->challengeService->challengeExists($model->task->id);
76 | if ($model->challenge) {
77 | $model->arena = $ctx->challengeService->arenaExists($model->task->id);
78 | }
79 |
80 | if (!empty($locale) && $locale != 'en') {
81 | $titlematch = array();
82 | if (preg_match('/\/',
83 | $model->task->statement, $titlematch)) {
84 | $model->task->title = $titlematch[1];
85 | }
86 | $ctx->elems->title .= " ({$alternativeLocales[$locale]})";
87 | }
88 | $ctx->elems->keywords = $model->tags;
89 | $ctx->elems->styles[] = 'jsmonoterm';
90 | $ctx->elems->scripts[] = 'jsmonoterm';
91 | $ctx->elems->analytics = true;
92 |
--------------------------------------------------------------------------------
/ctl/task/tag/Assign.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $tag = $ctx->util->paramPost('tag');
9 | $taskid = $ctx->util->paramPost('task');
10 |
11 | if (!is_numeric($taskid)) {
12 | $ctx->util->redirect('task_tag_edit');
13 | $ctx->util->flash("No task chosen!");
14 | return;
15 | }
16 |
17 | $returnLink = url('task_tag_edit', 'param', $taskid);
18 |
19 | $tag = strtolower(trim($tag));
20 |
21 | $tagObject = $ctx->tagsDao->findFirst("title = '$tag'");
22 |
23 | if (!is_object($tagObject)) {
24 | $ctx->util->redirect($returnLink);
25 | $ctx->util->flash("No such tag!");
26 | return;
27 | }
28 |
29 | $assignment = $ctx->taskTagsDao->findFirst("tagid = {$tagObject->id} and taskid = $taskid");
30 |
31 | if (is_object($assignment)) {
32 | $ctx->taskTagsDao->delete($assignment->id);
33 | $ctx->util->flash("Unassigned: $tag");
34 | } else {
35 | $assignment = new \stdClass();
36 | $assignment->tagid = $tagObject->id;
37 | $assignment->taskid = $taskid;
38 | $ctx->taskTagsDao->save($assignment);
39 | $ctx->util->flash("Assigned: $tag");
40 | }
41 |
42 | $ctx->util->redirect($returnLink);
43 |
44 |
--------------------------------------------------------------------------------
/ctl/task/tag/Edit.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $taskid = $ctx->util->paramGet('param');
9 |
10 | $model->tags = $ctx->tagsDao->makeLookup('id');
11 |
12 | if (!empty($taskid)) {
13 | $model->task = $ctx->tasksDao->read($taskid);
14 | $model->taskTags = $ctx->taskService->tagNamesForTask($taskid);
15 | } else {
16 | $model->task = null;
17 | $model->taskTags = array();
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/ctl/task/tag/List.php:
--------------------------------------------------------------------------------
1 | tags = $ctx->tagsDao->find();
4 |
5 | if ($ctx->auth->user()) {
6 | shuffle($model->tags);
7 | }
8 |
9 | $ctx->elems->scripts[] = 'cloud';
10 | $ctx->elems->title = 'Tags for Problems';
11 | $ctx->elems->analytics = true;
12 |
--------------------------------------------------------------------------------
/ctl/task/tag/Update.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $tag = $ctx->util->paramPost('tag');
9 | $taskid = $ctx->util->paramPost('task');
10 |
11 | $returnLink = url('task_tag_edit', 'param', $taskid);
12 |
13 | $tag = strtolower(trim($tag));
14 |
15 | if (!preg_match('/^[a-z]+(?:\-[a-z0-9]+)*$/', $tag)) {
16 | $ctx->util->redirect($returnLink);
17 | $ctx->util->flash("Bad tag title");
18 | return;
19 | }
20 |
21 | $existing = $ctx->tagsDao->findFirst("title = '$tag'");
22 | if (is_object($existing)) {
23 | $cnt = $ctx->taskTagsDao->getCount("tagid = {$existing->id}");
24 | if ($cnt > 0) {
25 | $ctx->util->flash("Some tasks have this tag");
26 | } else {
27 | $ctx->tagsDao->delete($existing->id);
28 | $ctx->util->flash("Removed: {$existing->title}");
29 | }
30 | } else {
31 | $entity = new \stdClass();
32 | $entity->title = $tag;
33 | $ctx->tagsDao->save($entity);
34 | $ctx->util->flash("Added: {$entity->title}");
35 | }
36 |
37 | $ctx->util->redirect($returnLink);
38 |
39 |
--------------------------------------------------------------------------------
/ctl/tools/Calcpoints.php:
--------------------------------------------------------------------------------
1 | elems->conf->calcPointsSecret
4 | || $ctx->util->paramGet('param') != $ctx->elems->conf->calcPointsSecret) {
5 | $ctx->util->changePage('error404');
6 | return;
7 | }
8 |
9 | $timeStart = microtime(true);
10 |
11 | $ctx->util->plainOutput("Calculations: \n");
12 |
13 | $taskPoints = $ctx->miscService->calcPoints();
14 |
15 | $timeEnd = microtime(true);
16 | $deltaTime = number_format(($timeEnd - $timeStart), 3);
17 |
18 | echo implode('', $taskPoints);
19 | echo "\nPoints Calculation completed in $deltaTime seconds\n";
20 |
--------------------------------------------------------------------------------
/ctl/user/Profile.php:
--------------------------------------------------------------------------------
1 | auth->user() ? $ctx->auth->loggedUser() : null;
5 |
6 | $url = $ctx->util->paramGet('param');
7 | if ($url) {
8 | if (is_numeric($url) && $url != '1') {
9 | $user = $ctx->usersDao->read($url);
10 | $ctx->util->redirect(url('user_profile', 'param', $user->url));
11 | return;
12 | }
13 | $user = $ctx->userService->byUrl($url);
14 | if (is_object($user)) {
15 | $userid = $user->id;
16 | }
17 | } elseif ($loggedUser) {
18 | $user = $ctx->usersDao->read($loggedUser);
19 | $ctx->util->redirect(url('user_profile', 'param', $user->url));
20 | return;
21 | }
22 |
23 | if (!is_numeric($userid)) {
24 | $userid = $loggedUser;
25 | }
26 |
27 | if (!is_numeric($userid)) {
28 | $ctx->util->changePage('error404');
29 | return;
30 | }
31 |
32 | $model->friendType = ($loggedUser !== null && $loggedUser !== $userid) ? $ctx->friendService->getFriendship($loggedUser, $userid) : null;
33 | $model->followedByCount = $ctx->friendService->followedByCount($userid);
34 | $model->followingCount = $ctx->friendService->followingCount($userid);
35 |
36 | if (empty($user) || !is_object($user)) {
37 | $user = $ctx->usersDao->read($userid);
38 | }
39 | $userdata = $ctx->userDataDao->findFirst("userid = $userid");
40 |
41 | if (!is_object($user) || !is_object($userdata)) {
42 | $ctx->util->changePage('error404');
43 | return;
44 | }
45 |
46 | $regType = substr($user->loginid, 0, 2);
47 |
48 | switch ($regType) {
49 | case 'gh':
50 | $user->socialnet = 'GitHub';
51 | $user->socialurl = 'https://github.com/' . preg_replace('/^.+\.(.+)$/', '\1', $user->loginid);
52 | break;
53 | default:
54 | $user->socialurl = null;
55 | }
56 |
57 | $userdata->created = $ctx->miscService->formatDate($userdata->created);
58 | $userdata->lastlogin = $ctx->miscService->formatDate($userdata->lastlogin, true);
59 | $model->data = $userdata;
60 | $model->user = $user;
61 | $model->cheat = $ctx->cheatService->status($user->id);
62 | $model->data->rank = $ctx->userService->rank($userdata->solved);
63 | $model->tasks = $ctx->userService->solvedTasks($user->id);
64 | $model->authored = $ctx->tasksDao->find("author = '{$user->url}'");
65 | $model->c1tagged = $ctx->userService->solvedTaggedTasks($user->id);
66 | $model->awards = $ctx->certService->forUser($user->id);
67 | $model->total = $ctx->userRankDao->getCount('solved > 0');
68 |
69 | $model->countries = null;
70 | $model->isCurrentUser = ($userid === $ctx->auth->loggedUser());
71 | $model->bannerUrl = $ctx->util->fullUrl(url('user_banner', 'param', $user->url . '.png'), 'https://');
72 |
73 | $personalInfo = $ctx->taskDataDao->findFirst("taskid = $userid and type = 'uinfo'");
74 | if (is_object($personalInfo)) {
75 | $ctx->markdown->no_markup = true;
76 | $model->personalInfo = trim($ctx->markdown->parse(base64_decode($personalInfo->data)));
77 | $ctx->markdown->no_markup = false;
78 | } else {
79 | $model->personalInfo = null;
80 | }
81 |
82 | $model->country = $ctx->miscService->countryNameByCode($userdata->country);
83 |
84 | $model->fbLike = array(
85 | 'url' => $ctx->util->fullUrl(url('user_profile', 'param', $model->user->url)),
86 | 'image' => $userdata->avatar,
87 | 'title' => "{$model->user->username} - watch my success at CodeAbbey!");
88 |
89 | $ctx->elems->robots = $userdata->solved >= 5 ? 'index,follow' : 'noindex,nofollow';
90 | $ctx->elems->title = $user->username . ' - user info';
91 | $ctx->elems->analytics = true;
92 |
93 |
--------------------------------------------------------------------------------
/ctl/user/Ranking.php:
--------------------------------------------------------------------------------
1 | util->paramGet('friends');
4 |
5 | $pageFromForm = $ctx->util->paramPost('pf');
6 | if (is_numeric($pageFromForm)) {
7 | $ctx->util->redirect(url('user_ranking', 'p', $pageFromForm - 1));
8 | return;
9 | }
10 |
11 | if ($ctx->util->paramGet('clr')) {
12 | $ctx->util->sessionDel('ranking-country');
13 | $ctx->util->sessionDel('ranking-language');
14 | $ctx->util->redirect(url('user_ranking'));
15 | return;
16 | }
17 |
18 | $model->country = $ctx->util->paramPost('country');
19 | if (empty($model->country)) {
20 | $model->country = $ctx->util->sessionGet('ranking-country');
21 | }
22 | $model->language = $ctx->util->paramPost('lang');
23 | if (empty($model->language)) {
24 | $model->language = $ctx->util->sessionGet('ranking-language');
25 | }
26 |
27 | $model->userid = $ctx->auth->loggedUser();
28 | if (!is_numeric($model->userid)) {
29 | $model->friends = null;
30 | } else {
31 | $model->friends = $friends ? $model->userid : null;
32 | }
33 |
34 | $countries = $ctx->countriesDao->makeLookup('code');
35 | if (!isset($countries[$model->country])) {
36 | $model->country = '';
37 | }
38 | $model->languages = $ctx->langService->languagesArray();
39 | if (!isset($model->languages[$model->language])) {
40 | $model->language = '';
41 | }
42 |
43 | if ($model->friends === null) {
44 | $page = $ctx->util->paramGet('p');
45 | $count = $ctx->userService->rankingPageSize;
46 | if (!is_numeric($page) || $page < 0 || $page > 100000000) {
47 | $page = 0;
48 | } else {
49 | $page = floor($page);
50 | }
51 |
52 | $query = 'solved > 0';
53 | if (!empty($model->country)) {
54 | $query .= " and country = '{$model->country}'";
55 | $ctx->util->sessionPut('ranking-country', $model->country);
56 | }
57 | if (!empty($model->language)) {
58 | $query .= " and language = '{$model->language}'";
59 | $ctx->util->sessionPut('ranking-language', $model->language);
60 | }
61 | } else {
62 | $friendIds = $ctx->friendService->followingAllIds($model->userid);
63 | if (!in_array($model->userid, $friendIds)) {
64 | $friendIds[] = $model->userid;
65 | }
66 | $page = 0;
67 | $count = count($friendIds);
68 | $friendIdsStr = implode(',', $friendIds);
69 | $query = "id in ($friendIdsStr)";
70 | }
71 | $model->total = $ctx->userRankDao->getCount($query);
72 | $model->rank = $ctx->userRankDao->find($query, $count, $page * $count);
73 | $model->page = $page;
74 | $model->count = $count;
75 |
76 |
77 | $userPresent = false;
78 | $loggedUser = $ctx->auth->user() ? $ctx->auth->loggedUser() : false;
79 |
80 | foreach ($model->rank as $entry) {
81 | if ($loggedUser !== false && $entry->id == $loggedUser) {
82 | $userPresent = true;
83 | $entry->current = true;
84 | } else {
85 | $entry->current = false;
86 | }
87 | $ctx->userService->additionalRankingData($entry, $countries);
88 | }
89 |
90 | if ($loggedUser !== false && !$userPresent) {
91 | $model->myRank = $ctx->userRankDao->findFirst("id = $loggedUser");
92 | $ctx->userService->additionalRankingData($model->myRank, $countries);
93 | $model->myRank->current = true;
94 | $model->myRank->before = $model->myRank->rankpos < $model->rank[0]->rankpos;
95 | } else {
96 | $model->myRank = null;
97 | }
98 |
99 | $model->countries = $countries;
100 |
101 | $ctx->elems->robots = $page < 5 ? 'index,follow' : 'noindex,nofollow';
102 | $ctx->elems->title = 'User ranking';
103 | $ctx->elems->analytics = true;
104 |
105 |
--------------------------------------------------------------------------------
/ctl/user/Settings.php:
--------------------------------------------------------------------------------
1 | auth->user()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $user = $ctx->usersDao->read($ctx->auth->loggedUser());
9 |
10 | $model->username = $user->username;
11 |
12 | $userdata = $ctx->userDataDao->findFirst("userid = {$user->id}");
13 |
14 | $model->country = $userdata->country;
15 |
16 | $model->countries = $ctx->countriesDao->find();
17 | foreach ($model->countries as $land) {
18 | $land->title = $land->code . ' - ' . $land->title;
19 | }
20 |
21 | $loginType = substr($user->loginid, 0, 2);
22 | $model->usesPwd = (strlen($user->password) >= 8);
23 | $model->nameForChange = (!$model->usesPwd || $userdata->solved >= $ctx->elems->conf->nameChangeLevel)
24 | ? $user->username : null;
25 | $model->email = ($loginType == '!!'
26 | ? preg_replace('/(.)[^\@]+(\@.+)/', '\1***\2', substr($user->loginid, 2))
27 | : null);
28 | $model->ghname = ($loginType == 'gh')
29 | ? preg_replace('/.*\./', '', $user->loginid) : '';
30 |
31 | $model->avatar = $userdata->avatar;
32 |
33 | $personalInfo = $ctx->taskDataDao->findFirst("taskid = {$user->id} and type = 'uinfo'");
34 | $model->personalInfo = is_object($personalInfo)
35 | ? base64_decode($personalInfo->data) : "";
36 |
37 |
--------------------------------------------------------------------------------
/ctl/user/Unsolved.php:
--------------------------------------------------------------------------------
1 | util->paramGet('param');
4 | $user = $ctx->userService->byUrl($url);
5 | if (!is_object($user)) {
6 | $ctx->util->changePage('error404');
7 | return;
8 | }
9 |
10 | $model->userName = $user->username;
11 | $model->userUrl = $user->url;
12 |
13 | $userTasks = $ctx->userTasksDao->find("userid = {$user->id} and solved <= 0");
14 | if (!empty($userTasks)) {
15 | $taskIds = $ctx->miscService->listIds($userTasks, 'taskid');
16 | $tasks = $ctx->tasksDao->makeLookup('id', "id in ($taskIds)");
17 | }
18 |
19 | $neverSolved = $ctx->userTasksDao->neverSolvedIds($user->id);
20 |
21 | $model->entries = array();
22 |
23 | foreach ($userTasks as $entry) {
24 | $task = $tasks[$entry->taskid];
25 | $entry->title = $task->title;
26 | $entry->taskUrl = url('task_view', 'param', $task->url);
27 | $entry->url = url('task_solution', 'user', $user->url, 'task', $task->url, 'lang', urlencode($entry->language));
28 | $entry->ts = $ctx->miscService->formatDate($entry->ts);
29 | $entry->neverSolved = in_array($entry->taskid, $neverSolved);
30 | }
31 |
32 | usort($userTasks, function($a, $b) {
33 | return $a->taskid - $b->taskid;
34 | });
35 |
36 | $model->records = $userTasks;
37 |
38 | $ctx->elems->robots = 'noindex,nofollow';
39 | $ctx->elems->title = $user->username . ' - unsuccessful solutions';
40 | $ctx->elems->analytics = true;
41 |
--------------------------------------------------------------------------------
/ctl/user/settings/Avatar.php:
--------------------------------------------------------------------------------
1 | util->paramPost('url');
4 | $userid = $ctx->auth->loggedUser();
5 |
6 | if (empty($userid)) {
7 | $ctx->util->changePage('error404');
8 | return;
9 | }
10 |
11 | $check = function($url) {
12 | if (preg_match('/^http[s]?\:\/\/[a-zA-Z0-9\-\_\.\/]+$/', $url) != 1) {
13 | return "Invalid URL!";
14 | }
15 | $image = @getimagesize($url);
16 | if ($image === false) {
17 | return "Image loading failed";
18 | }
19 | if ($image[0] < 100 || $image[1] < 100) {
20 | return "Image is too small - min 100px";
21 | }
22 | if ($image[0] > 300 || $image[1] > 300) {
23 | return "Image is too large - max 300px";
24 | }
25 | if ($image[2] != IMAGETYPE_JPEG && $image[2] != IMAGETYPE_JPEG2000 && $image[2] != IMAGETYPE_PNG) {
26 | return "Image should be JPEG or PNG " . $image[2];
27 | }
28 | return "";
29 | };
30 |
31 | if (!empty($url)) {
32 | $message = $check($url);
33 | } else {
34 | $message = "";
35 | $url = "";
36 | }
37 |
38 | if ($message == "") {
39 | $userdata = $ctx->userDataDao->findFirst("userid = $userid");
40 | $userdata->avatar = $url;
41 | $ctx->userDataDao->save($userdata);
42 | $ctx->util->flash("OK!");
43 | } else {
44 | $ctx->util->flash($message);
45 | }
46 |
47 | $ctx->util->redirect("user_settings");
48 |
49 |
--------------------------------------------------------------------------------
/ctl/user/settings/Chname.php:
--------------------------------------------------------------------------------
1 | util->paramPost('newname');
4 |
5 | if (!$ctx->auth->user() || empty($newname)) {
6 | $ctx->util->changePage('error404');
7 | return;
8 | }
9 |
10 | $user = $ctx->usersDao->findFirst("id = " . $ctx->auth->loggedUser());
11 | $userData = $ctx->userDataDao->findFirst("userid = {$user->id}");
12 |
13 | $loginType = substr($user->loginid, 0, 2);
14 | if ($loginType == '!!') {
15 | if ($userData->solved < $ctx->elems->conf->nameChangeLevel) {
16 | $ctx->util->changePage('error404');
17 | return;
18 | }
19 | }
20 |
21 | $checkName = $ctx->userService->checkNewUsername($newname, true);
22 | if ($checkName !== null) {
23 | $ctx->util->flash("Error: $checkName");
24 | $ctx->util->redirect('user_profile');
25 | return;
26 | }
27 |
28 | if (!$ctx->cheatService->isSuspended($user->id)) {
29 | $user->username = $newname;
30 | $ctx->usersDao->save($user);
31 | }
32 |
33 | $ctx->util->flash('Name was changed!');
34 | $ctx->util->redirect('user_settings');
35 |
36 |
--------------------------------------------------------------------------------
/ctl/user/settings/Country.php:
--------------------------------------------------------------------------------
1 | util->paramPost('code');
4 | $userid = $ctx->auth->loggedUser();
5 |
6 | if (empty($userid) || empty($code) || !preg_match('/[a-z]{2,3}/i', $code)) {
7 | $ctx->util->changePage('error404');
8 | return;
9 | }
10 |
11 | $country = $ctx->countriesDao->findFirst("code = '$code'");
12 |
13 | if (!is_object($country)) {
14 | $ctx->util->changePage('error404');
15 | return;
16 | }
17 |
18 | $userdata = $ctx->userDataDao->findFirst("userid = $userid");
19 | $userdata->country = $code;
20 | $ctx->userDataDao->save($userdata);
21 |
22 | $ctx->util->flash('Country info updated!');
23 | $ctx->util->redirect('user_settings');
24 |
--------------------------------------------------------------------------------
/ctl/user/settings/Email.php:
--------------------------------------------------------------------------------
1 | util->paramPost('newemail');
4 | $pwd = $ctx->util->paramPost('chkpwd');
5 | $userid = $ctx->auth->loggedUser();
6 |
7 | if (empty($userid) || is_null($email) || is_null($pwd)) {
8 | $ctx->util->changePage('error404');
9 | return;
10 | }
11 |
12 | $user = $ctx->usersDao->findFirst("id = $userid");
13 |
14 | if (substr($user->loginid, 0, 2) != '!!') {
15 | $ctx->util->changePage('error404');
16 | return;
17 | }
18 |
19 | if ($ctx->loginService->hashPassword($pwd) != $user->password) {
20 | $message = 'Error: Password is wrong!';
21 | } else {
22 | $chk = $ctx->userService->checkEmail($email);
23 | if (is_null($chk)) {
24 | $user->loginid = '!!' . $ctx->loginService->hashEmail($email);
25 | $ctx->usersDao->save($user);
26 | $message = 'E-mail updated! ';
27 | } else {
28 | $message = "Error: $chk";
29 | }
30 | }
31 |
32 | $ctx->util->flash($message);
33 | $ctx->util->redirect('user_settings');
34 |
--------------------------------------------------------------------------------
/ctl/user/settings/Info.php:
--------------------------------------------------------------------------------
1 | util->paramPost('info');
4 |
5 | if (!$ctx->userService->personalInfoAllowed()) {
6 | $ctx->util->changePage('error404');
7 | return;
8 | }
9 |
10 | $userid = $ctx->auth->loggedUser();
11 |
12 | $userInfo = $ctx->taskDataDao->findFirst("taskid = $userid and type = 'uinfo'");
13 | if (!is_object($userInfo)) {
14 | $userInfo = new \stdClass();
15 | $userInfo->taskid = $userid;
16 | $userInfo->type = 'uinfo';
17 | }
18 | $userInfo->data = base64_encode($info);
19 | $ctx->taskDataDao->save($userInfo);
20 |
21 | $ctx->util->redirect('user_profile');
22 |
--------------------------------------------------------------------------------
/ctl/user/settings/Password.php:
--------------------------------------------------------------------------------
1 | util->paramPost('newpwd');
4 | $reppwd = $ctx->util->paramPost('reppwd');
5 | $oldpwd = $ctx->util->paramPost('oldpwd');
6 | $userid = $ctx->auth->loggedUser();
7 |
8 | if (empty($userid) || is_null($newpwd) || is_null($reppwd) || is_null($oldpwd)) {
9 | $ctx->util->changePage('error404');
10 | return;
11 | }
12 |
13 | $user = $ctx->usersDao->findFirst("id = $userid");
14 |
15 | $wrong = true;
16 | $providedHash = $ctx->loginService->hashPassword($oldpwd);
17 | if ($providedHash == $user->password) {
18 | $wrong = false;
19 | } else {
20 | $tempPwd = $ctx->miscService->getTaggedValue("pwd-{$user->id}");
21 | if ($tempPwd) {
22 | list($ts, $tempHash) = explode(' ', $tempPwd);
23 | if ($tempHash == $providedHash) {
24 | $wrong = false;
25 | }
26 | }
27 | }
28 |
29 | if ($wrong) {
30 | $message = 'Error: Password is wrong!';
31 | } else {
32 | $chk = $ctx->userService->checkPassword($newpwd, $reppwd);
33 | if (is_null($chk)) {
34 | $user->password = $ctx->loginService->hashPassword($newpwd);
35 | $ctx->usersDao->save($user);
36 | $message = 'Password updated! ';
37 | $ctx->miscService->logAction($userid, 'pwd changed');
38 | } else {
39 | $message = "Error: $chk";
40 | }
41 | }
42 |
43 | $ctx->util->flash($message);
44 | $ctx->util->redirect('user_settings');
45 |
--------------------------------------------------------------------------------
/ctl/wiki/Edit.php:
--------------------------------------------------------------------------------
1 | auth->admin()) {
4 | $ctx->util->changePage('error404');
5 | return;
6 | }
7 |
8 | $title = $ctx->util->paramGet('url');
9 |
10 | if (!empty($title)) {
11 | $model->wikipage = $ctx->wikiDao->findFirst("url = '$title'");
12 | if (!is_object($model->wikipage)) {
13 | $ctx->util->changePage('error404');
14 | return;
15 | }
16 | $model->wikipage->data = base64_decode($model->wikipage->data);
17 | } else {
18 | $model->wikipage = new stdClass();
19 | $model->wikipage->title = '';
20 | $model->wikipage->url = '';
21 | $model->wikipage->data = '';
22 | }
23 |
24 | array_push($ctx->elems->styles, 'codemirror');
25 | array_push($ctx->elems->scripts, '_cm/codemirror');
26 | array_push($ctx->elems->scripts, '_cm/markdown');
27 | array_push($ctx->elems->scripts, '_cm/xml');
28 |
--------------------------------------------------------------------------------
/ctl/wiki/Save.php:
--------------------------------------------------------------------------------
1 | util->paramPost('title');
4 | $url = $ctx->util->paramPost('url');
5 | $data = $ctx->util->paramPost('data');
6 |
7 | if (!$ctx->auth->admin() || empty($title) || empty($url)) {
8 | $ctx->util->changePage('error404');
9 | return;
10 | }
11 |
12 | $url = $ctx->strUtils->nameToUrl($url);
13 | $wikipage = $ctx->wikiDao->findFirst("url = '$url'");
14 | if (!is_object($wikipage)) {
15 | $wikipage = new stdClass();
16 | }
17 |
18 | if (trim($data) != 'DELETE') {
19 | $wikipage->title = $title;
20 | $wikipage->url = $url;
21 | $wikipage->data = base64_encode($data);
22 | $wikipage->lastmod = date('Y-m-d');
23 |
24 | $ctx->wikiDao->save($wikipage);
25 |
26 | $ctx->util->redirect(url('wiki', 'param', $wikipage->url));
27 | } else {
28 | if ($wikipage->id) {
29 | $ctx->wikiDao->delete($wikipage->id);
30 | $ctx->util->flash("Wiki on $url was deleted!");
31 | } else {
32 | $ctx->util->flash("Page to delete was not found!");
33 | }
34 | $ctx->util->redirect('wiki');
35 | }
--------------------------------------------------------------------------------
/docker-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | docker build --tag ca-base .
--------------------------------------------------------------------------------
/docker-run.sh:
--------------------------------------------------------------------------------
1 | docker run --rm --name ca-run -p 8080:80 -v $(pwd):/var/www/html -e CA_TEST=1 ca-base
2 |
--------------------------------------------------------------------------------
/fragments/.htaccess:
--------------------------------------------------------------------------------
1 | Order deny,allow
2 | Deny from all
3 |
--------------------------------------------------------------------------------
/fragments/countryselect.html:
--------------------------------------------------------------------------------
1 |
2 | --- Select Country ---
3 | countries as $countryVal => $country) : ?>
4 | country ? 'selected="true"' : ''?> value="= $countryVal ?>">= $country->title ?>
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/fragments/cssandjs.html:
--------------------------------------------------------------------------------
1 | util->sessionGet('css-random-key');
4 | if ($cssRandomKey === null) {
5 | $cssRandomKey = rand();
6 | $ctx->util->sessionPut('css-random-key', $cssRandomKey);
7 | }
8 |
9 | foreach ($ctx->elems->styles as $name) {
10 | if (strpos($name, '.') === false) $name .= ".css";
11 | $file = "css/$name";
12 | $tag = ' ";
13 | if (!file_exists($file)) {
14 | $tag = "";
15 | }
16 | echo "$tag\n";
17 | }
18 |
19 | echo '';
20 |
21 | foreach ($ctx->elems->scripts as $name) {
22 | if (strpos($name, '://') !== false) {
23 | echo "";
24 | continue;
25 | }
26 | if (strpos($name, '.') === false) $name .= ".js";
27 | $file = "js/$name";
28 | $tag = '";
29 | if (!file_exists($file)) {
30 | $tag = "";
31 | }
32 | echo "$tag\n";
33 | }
34 |
35 | ?>
36 |
--------------------------------------------------------------------------------
/fragments/flash.html:
--------------------------------------------------------------------------------
1 | util->flash();
3 | if ($_flash !== null) :
4 | ?>
5 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/fragments/footer.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/fragments/forumform.html:
--------------------------------------------------------------------------------
1 |
8 |
48 |
49 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/fragments/langselect.html:
--------------------------------------------------------------------------------
1 |
2 | --- Select Language ---
3 | languages as $langVal => $langName) : ?>
4 | language ? 'selected="true"' : ''?> value="= $langVal ?>">= $langName ?>
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/fragments/main/bottomnote.html:
--------------------------------------------------------------------------------
1 |
2 | Do you know you can set up similar website in 15 minutes? Check link at the bottom of the page!
3 |
4 |
--------------------------------------------------------------------------------
/fragments/main/image.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/fragments/main/lastforum.html:
--------------------------------------------------------------------------------
1 |
2 |
7 | lastForum as $topic) : ?>
8 |
11 |
12 | from = $topic->user->username ?> ,
13 | last = $topic->lastUser->username ?>
14 |
15 |
16 | last at = $topic->lastpost ?>
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/fragments/main/lasttasks.html:
--------------------------------------------------------------------------------
1 | Latest problems
2 | lastTasks as $task): ?>
3 | = $task->title ?>
4 | #= $task->id ?>
5 |
6 |
7 |
--------------------------------------------------------------------------------
/fragments/main/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | logged) : ?>
4 |
18 |
19 |
Hello, = $ctx->auth->username() ?>!
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/fragments/main/middlenote.html:
--------------------------------------------------------------------------------
1 | What certificates and achievements can you win here? Learn more...
2 |
3 |
--------------------------------------------------------------------------------
/fragments/main/rank.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
Top Brethren and Sistren of the Week
9 |
(see best of all times)
10 |
11 |
12 |
13 | User
14 | Rank
15 | Solved
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/fragments/menu-bs.html:
--------------------------------------------------------------------------------
1 |
9 |
10 | auth->loggedUser() !== null): ?>
11 |
27 |
28 |
29 |
30 | = date('H:i:s') ?>
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/fragments/metas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | elems->get('robots', 'index,follow'); ?>
4 |
5 | elems->conf->canonical) && strpos($metaRobots, 'noindex') === false): ?>
6 |
7 |
8 |
--------------------------------------------------------------------------------
/fragments/rankline.html:
--------------------------------------------------------------------------------
1 | curEntry ?>
2 |
3 | = $entry->rankpos ?>
4 |
5 | avatar != '') : ?>
6 |
8 |
9 |
10 |
11 |
12 |
13 | = $entry->username ?>
14 |
15 |
18 |
19 | = $entry->language ?>
20 | = $entry->rank ?>
21 | = $entry->points ?>
22 | = $entry->solved ?>
23 |
24 |
25 |
--------------------------------------------------------------------------------
/fragments/tasklist/notice.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/fragments/taskview/badattempt.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
11 |
13 |
14 |
15 | Please kindly wait a bit for results...
16 |
17 |
18 |
19 |
Expected answer was:
20 |
21 |
22 |
23 |
24 |
Click to view answer you
25 | submitted...
26 |
Your answer was:
27 |
28 |
29 |
30 |
31 |
Click to view input data if you
32 | haven't saved it...
33 |
Your input data:
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/fragments/taskview/errorsmodal.html:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/fragments/taskview/runtools.html:
--------------------------------------------------------------------------------
1 |
20 |
--------------------------------------------------------------------------------
/fragments/taskview/solcaption.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Your solution:
5 |
6 |
Note: it is not checked automatically, it is saved so you
7 | can later reuse your code in other problems.
8 | You can write in any language you want .
9 | For some of them we have built-in tools (see buttons below on right).
10 |
11 |
12 |
Select Language:
13 |
14 | Autodetect
15 | languages as $langKey => $langVal) : ?>
16 | = $langVal ?>
17 |
18 |
19 |
Run
20 |
21 |
26 |
27 |
--------------------------------------------------------------------------------
/img/facade.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/facade.gif
--------------------------------------------------------------------------------
/img/flags/zz.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/flags/zz.gif
--------------------------------------------------------------------------------
/img/logingg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/logingg.png
--------------------------------------------------------------------------------
/img/logingh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/logingh.png
--------------------------------------------------------------------------------
/img/logout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/logout.png
--------------------------------------------------------------------------------
/img/profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/profile.png
--------------------------------------------------------------------------------
/img/random.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/random.png
--------------------------------------------------------------------------------
/img/search2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/search2.png
--------------------------------------------------------------------------------
/img/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeAbbey/src/602af91940566457fb7fe639e603f1a5db9ea91c/img/settings.png
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | elems->page);
11 | $ctlFile = "ctl/$ctlName.php";
12 | $r = addfile($ctlFile);
13 |
14 | addFile("ctl/_hookPreRender.php");
15 |
16 | if ($ctx->elems->page != null) {
17 | array_push($ctx->elems->styles, $ctx->elems->page);
18 | array_push($ctx->elems->scripts, $ctx->elems->page);
19 | $content = 'pages/' . $ctx->elems->page . '.php';
20 | ob_start();
21 | if (!addfile($content)) {
22 | addfile('pages/error404.php');
23 | }
24 | $ctx->elems->contentResult = ob_get_clean();
25 |
26 | ob_start();
27 | require('layouts/' . $ctx->elems->layout . '.html');
28 | $rendered = ob_get_clean();
29 | echo $rendered;
30 | }
31 |
32 | addFile("ctl/_hookAfter.php");
33 |
34 | destroyModules();
35 | }
36 |
37 | function capitalizeReplace($m) {
38 | return ucfirst($m[0]);
39 | }
40 |
41 | function prepare() {
42 | global $model, $ctx;
43 |
44 | new \module\sys\Elems();
45 | $model = new \stdClass();
46 |
47 | $ctx = new \module\Context();
48 |
49 | addFile('conf.php');
50 | addFile('cust_conf.php');
51 |
52 | $ctx->elems->path = preg_replace('/^(.*\/)[^\/]*$/', '$1', $_SERVER['PHP_SELF']);
53 |
54 | $page = isset($_GET['page']) ? $_GET['page'] : 'main';
55 | $page = preg_replace('/[^a-z0-9\_]/', '', $page);
56 | $page = str_replace('_', '/', $page);
57 |
58 | $ctx->elems->page = $page;
59 |
60 | }
61 |
62 |
63 | function destroyModules() {
64 | global $ctx;
65 | for ($i = sizeof($ctx->elems->moduleOrder) - 1; $i >= 0; $i --) {
66 | $moduleClass = $ctx->elems->modules[$ctx->elems->moduleOrder[$i]];
67 | if (method_exists($moduleClass, 'onModuleDestroy')) {
68 | call_user_func("$moduleClass::onModuleDestroy");
69 | }
70 | }
71 | }
72 |
73 |
74 | function addfile($name) {
75 | global $model, $ctx;
76 | if (!file_exists($name)) {
77 | return false;
78 | }
79 | include($name);
80 | return true;
81 | }
82 |
83 |
84 | function url($name) {
85 | global $ctx;
86 | $path = $ctx->elems->path;
87 | $rewrite = $ctx->elems->conf->modrewrite;
88 | $res = $rewrite ? "{$path}index/$name" : "{$path}index.php?page=$name";
89 |
90 | $numArgs = func_num_args();
91 | if ($numArgs == 3) {
92 | $args = func_get_args();
93 | if ($rewrite) {
94 | $pname = $args[1];
95 | if ($pname != 'param') {
96 | $res .= "/{$args[1]}_{$args[2]}";
97 | } else {
98 | $res .= "/{$args[2]}";
99 | }
100 | } else {
101 | $res .= "&{$args[1]}={$args[2]}";
102 | }
103 | } else if ($numArgs > 3) {
104 | $i = 1;
105 | $args = func_get_args();
106 | $query = array();
107 | while ($i < $numArgs - 1) {
108 | if ($args[$i] !== null && $args[$i + 1] !== null) {
109 | array_push($query, $args[$i] . "=" . $args[$i + 1]);
110 | }
111 | $i += 2;
112 | }
113 | $res .= ($rewrite ? '?' : '&') . implode('&', $query);
114 | }
115 | return $res;
116 | }
117 |
118 |
119 | function aurl($url) {
120 | global $ctx;
121 | return $ctx->elems->path . $url;
122 | }
123 |
124 | spl_autoload_register(function($class) {
125 | $path = str_replace('\\', '/', $class) . '.php';
126 | if ((@include $path) === false) {
127 | echo "Loading $class file failed!\n";
128 | } elseif (!class_exists($class, false) && !interface_exists($class, false)) {
129 | echo "Loading $class failed!\n";
130 | }
131 | });
132 |
133 | main();
134 |
--------------------------------------------------------------------------------
/js/_ace/mode-plain_text.js:
--------------------------------------------------------------------------------
1 | ace.define("ace/mode/plain_text",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/behaviour"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=e("./behaviour").Behaviour,u=function(){this.HighlightRules=s,this.$behaviour=new o};r.inherits(u,i),function(){this.type="text",this.getNextLineIndent=function(e,t,n){return t.match(/^\s*/)[0]},this.$id="ace/mode/plain_text"}.call(u.prototype),t.Mode=u})
2 |
--------------------------------------------------------------------------------
/js/_ace/mode-python.js:
--------------------------------------------------------------------------------
1 | ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")",m="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define("ace/mode/python",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/python_highlight_rules","ace/mode/folding/pythonic","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:")};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python"}.call(a.prototype),t.Mode=a})
--------------------------------------------------------------------------------
/js/_ace/mode-sql.js:
--------------------------------------------------------------------------------
1 | define("ace/mode/sql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="select|insert|update|delete|from|where|and|or|group|by|order|limit|offset|having|as|case|when|then|else|end|type|left|right|join|on|outer|desc|asc|union|create|table|primary|key|if|foreign|not|references|default|null|inner|cross|natural|database|drop|grant|distinct",t="true|false",n="avg|count|first|last|max|min|sum|ucase|lcase|mid|len|round|rank|now|format|coalesce|ifnull|isnull|nvl",r="int|numeric|decimal|date|varchar|char|bigint|float|double|bit|binary|text|set|timestamp|money|real|number|integer",i=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t,"storage.type":r},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"comment",start:"/\\*",end:"\\*/"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"string",regex:"`.*?`"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]},this.normalizeRules()};r.inherits(s,i),t.SqlHighlightRules=s}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/folding/sql",["require","exports","module","ace/lib/oop","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./cstyle").FoldMode,s=t.FoldMode=function(){};r.inherits(s,i),function(){}.call(s.prototype)}),define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sql_highlight_rules","ace/mode/folding/sql"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sql_highlight_rules").SqlHighlightRules,o=e("./folding/sql").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o,this.$behaviour=this.$defaultBehaviour};r.inherits(u,i),function(){this.lineCommentStart="--",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/sql",this.snippetFileId="ace/snippets/sql"}.call(u.prototype),t.Mode=u}); (function() {
2 | window.require(["ace/mode/sql"], function(m) {
3 | if (typeof module == "object" && typeof exports == "object" && module) {
4 | module.exports = m;
5 | }
6 | });
7 | })();
8 |
--------------------------------------------------------------------------------
/js/_ace/test-it.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/js/_cm/matchbrackets.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
3 | (document.documentMode == null || document.documentMode < 8);
4 |
5 | var Pos = CodeMirror.Pos;
6 |
7 | var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
8 | function findMatchingBracket(cm, where, strict) {
9 | var state = cm.state.matchBrackets;
10 | var maxScanLen = (state && state.maxScanLineLength) || 10000;
11 |
12 | var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1;
13 | var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
14 | if (!match) return null;
15 | var forward = match.charAt(1) == ">", d = forward ? 1 : -1;
16 | if (strict && forward != (pos == cur.ch)) return null;
17 | var style = cm.getTokenTypeAt(Pos(cur.line, pos + 1));
18 |
19 | var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
20 | function scan(line, lineNo, start) {
21 | if (!line.text) return;
22 | var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1;
23 | if (line.text.length > maxScanLen) return null;
24 | if (start != null) pos = start + d;
25 | for (; pos != end; pos += d) {
26 | var ch = line.text.charAt(pos);
27 | if (re.test(ch) && cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style) {
28 | var match = matching[ch];
29 | if (match.charAt(1) == ">" == forward) stack.push(ch);
30 | else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
31 | else if (!stack.length) return {pos: pos, match: true};
32 | }
33 | }
34 | }
35 | for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {
36 | if (i == cur.line) found = scan(line, i, pos);
37 | else found = scan(cm.getLineHandle(i), i);
38 | if (found) break;
39 | }
40 | return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos),
41 | match: found && found.match, forward: forward};
42 | }
43 |
44 | function matchBrackets(cm, autoclear) {
45 | // Disable brace matching in long lines, since it'll cause hugely slow updates
46 | var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
47 | var found = findMatchingBracket(cm);
48 | if (!found || cm.getLine(found.from.line).length > maxHighlightLen ||
49 | found.to && cm.getLine(found.to.line).length > maxHighlightLen)
50 | return;
51 |
52 | var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
53 | var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style});
54 | var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style});
55 | // Kludge to work around the IE bug from issue #1193, where text
56 | // input stops going to the textare whever this fires.
57 | if (ie_lt8 && cm.state.focused) cm.display.input.focus();
58 | var clear = function() {
59 | cm.operation(function() { one.clear(); two && two.clear(); });
60 | };
61 | if (autoclear) setTimeout(clear, 800);
62 | else return clear;
63 | }
64 |
65 | var currentlyHighlighted = null;
66 | function doMatchBrackets(cm) {
67 | cm.operation(function() {
68 | if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
69 | if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false);
70 | });
71 | }
72 |
73 | CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
74 | if (old && old != CodeMirror.Init)
75 | cm.off("cursorActivity", doMatchBrackets);
76 | if (val) {
77 | cm.state.matchBrackets = typeof val == "object" ? val : {};
78 | cm.on("cursorActivity", doMatchBrackets);
79 | }
80 | });
81 |
82 | CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
83 | CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){
84 | return findMatchingBracket(this, pos, strict);
85 | });
86 | })();
87 |
--------------------------------------------------------------------------------
/js/jq_bs_cm.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | = $ctx->miscService->formatTitle() ?>
6 |
7 |
8 |
9 | elems->locales)) : ?>
10 | elems->locales as $localeCode => $localeUrl) : ?>
11 |
12 |
13 |
14 |
15 | util->fragment('metas'); ?>
16 | elems->styles, 0, 0, ['bs_cm.php']);
18 | array_splice($ctx->elems->scripts, 0, 0, ['jq_bs_cm.php']);
19 | ?>
20 |
21 | util->fragment('cssandjs'); ?>
22 |
23 |
24 |
25 |
30 |
31 |
32 | = $ctx->util->fragment('flash'); ?>
33 |
34 | msgService->getMessagePersonal();
36 | if (!empty($msgPersonal)) : ?>
37 |
38 | = $msgPersonal ?>(click to remove)
39 |
40 |
41 |
42 | = $ctx->elems->get('contentResult', '
No content
') ?>
43 |
44 |
45 |
50 |
51 | elems->errors) > 0) {
53 | echo '' . join("\n \n", $ctx->elems->errors) . '
';
54 | }
55 | ?>
56 |
57 | elems->analytics) && $ctx->elems->analytics && !$ctx->auth->admin()) : ?>
58 | elems->conf->debug)) : ?>
59 |
60 |
61 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/module/.htaccess:
--------------------------------------------------------------------------------
1 | Order deny,allow
2 | Deny from all
3 |
--------------------------------------------------------------------------------
/module/Context.php:
--------------------------------------------------------------------------------
1 | ctx->usersDao->findFirst("username = '$username'");
10 | if ($record === false) {
11 | return false;
12 | }
13 | if ($record->password != $password) {
14 | $tempPwd = $this->ctx->miscService->getTaggedValue("pwd-{$record->id}");
15 | if (!$tempPwd) {
16 | return false;
17 | }
18 | list($ts, $hash) = explode(' ', $tempPwd);
19 | if ($ts + 1800 < time() || $hash != $password) {
20 | return false;
21 | }
22 | }
23 | $this->ctx->util->sessionPut('userid', $record->id);
24 | return true;
25 | }
26 |
27 | function logout() {
28 | $this->ctx->util->sessionDel('userid');
29 | }
30 |
31 | function check($role) {
32 | $userid = $this->loggedUser();
33 | if ($userid === null) {
34 | return false;
35 | }
36 | return $this->ctx->rolesDao->findFirst("userid = $userid and role = '$role'") !== false;
37 | }
38 |
39 | protected function checkWithHeader($role, $header, $page) {
40 | if ($this->check($role)) {
41 | return true;
42 | }
43 | $this->ctx->util->changePage($page);
44 | header($header);
45 | return false;
46 | }
47 |
48 | public function loggedUser() {
49 | return $this->ctx->util->sessionGet('userid');
50 | }
51 |
52 | function checkWith403($role) {
53 | return $this->checkWithHeader($role, 'HTTP/1.0 403 Forbidden', 'error403');
54 | }
55 |
56 | function checkWith404($role) {
57 | return $this->checkWithHeader($role, 'HTTP/1.0 404 Not Found', 'error404');
58 | }
59 |
60 | function checkWithRedirect($role, $url) {
61 | return $this->checkWithHeader($role, "Location: $url");
62 | }
63 |
64 | function admin() {
65 | return $this->check('admin');
66 | }
67 |
68 | function user() {
69 | return $this->check('user');
70 | }
71 |
72 | function username() {
73 | $id = $this->loggedUser();
74 | if (!$id) {
75 | return '';
76 | }
77 | $user = $this->ctx->usersDao->read($id);
78 | return $user->username;
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/module/dao/ChallengesDao.php:
--------------------------------------------------------------------------------
1 | query("select userid, sum(total) as points from "
13 | . $this->getTable() . " where userid <> 0 group by userid");
14 | $res = $this->objectsArray($res);
15 | $lookup = array();
16 | foreach ($res as $rec) {
17 | $lookup[$rec->userid] = $rec->points;
18 | }
19 | return $lookup;
20 | }
21 |
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/module/dao/ForumTopicsDao.php:
--------------------------------------------------------------------------------
1 | query('select * from '
13 | . $this->getTable() . " where lastpost > '$from' order by lastpost desc limit 20");
14 | return $this->objectsArray($res);
15 | }
16 |
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/module/dao/MysqlDao.php:
--------------------------------------------------------------------------------
1 | table = self::$shared['prefix'] . $table;
16 | $this->entityClass = $entityClass;
17 | $this->conn = self::$shared['conn'];
18 | }
19 |
20 | function read($id) {
21 | $query = "select * from {$this->table} where id = $id";
22 | $res = $this->conn->query($query);
23 |
24 | if ($res === false || $res->num_rows < 1) {
25 | return false;
26 | }
27 |
28 | $res = $this->objectsArray($res);
29 | return $res[0];
30 | }
31 |
32 | function save($entity) {
33 | $a = [];
34 | foreach (((array) $entity) as $k => $v) {
35 | if ($v === null) continue;
36 | $a[$k] = $this->conn->escape_string($v);
37 | }
38 | $names = implode(',', array_keys($a));
39 | $values = implode('","', array_values($a));
40 | $query = sprintf('replace into %s (%s) values ("%s")', $this->table, $names, $values);
41 | $res = $this->conn->query($query);
42 | if ($res === false) {
43 | return false;
44 | }
45 | if (isset($entity->id) && $entity->id !== null) {
46 | return $entity->id;
47 | }
48 | return $this->conn->insert_id;
49 | }
50 |
51 | function delete($id) {
52 | $query = "delete from {$this->table} where id = $id";
53 | return $this->conn->query($query);
54 | }
55 |
56 | function findIds($cond = null, $limit = null, $offset = null) {
57 | $query = "select id from {$this->table}";
58 | $query .= $this->clauses($cond, $limit, $offset);
59 | $res = $this->conn->query($query);
60 |
61 | return $this->singleFieldArray($res);
62 | }
63 |
64 | function find($cond = null, $limit = null, $offset = null) {
65 | $query = "select * from {$this->table}";
66 | $query .= $this->clauses($cond, $limit, $offset);
67 | $res = $this->conn->query($query);
68 |
69 | return $this->objectsArray($res);
70 | }
71 |
72 | function makeLookup($key = 'id', $cond = null) {
73 | $res = $this->find($cond);
74 | $lookup = array();
75 | foreach ($res as $val) {
76 | $lookup[$val->$key] = $val;
77 | }
78 | return $lookup;
79 | }
80 |
81 | function findFirst($cond = null) {
82 | $res = $this->find($cond, 1);
83 | if ($res === false || sizeof($res) < 1) {
84 | return false;
85 | }
86 | return $res[0];
87 | }
88 |
89 | function getCount($cond = null) {
90 | $query = "select count(*) from {$this->table}";
91 | $query .= $this->clauses($cond, null, null);
92 | $res = $this->conn->query($query);
93 | $res = $this->singleFieldArray($res);
94 | return $res[0];
95 | }
96 |
97 | protected function query($query) {
98 | return $this->conn->query($query);
99 | }
100 |
101 | private function clauses($cond, $limit, $offset) {
102 | if ($cond !== null) {
103 | $query = " where $cond";
104 | } else {
105 | $query = "";
106 | }
107 | if ($offset !== null) {
108 | $query .= " limit $offset, $limit";
109 | } else if ($limit !== null) {
110 | $query .= " limit $limit";
111 | }
112 | return $query;
113 | }
114 |
115 | protected function objectsArray($res) {
116 | if ($res === false) {
117 | return false;
118 | }
119 |
120 | $a = array();
121 | while (true) {
122 | $o = $res->fetch_object($this->entityClass);
123 | if ($o === null) {
124 | break;
125 | }
126 | array_push($a, $o);
127 | }
128 |
129 | return $a;
130 | }
131 |
132 | protected function singleFieldArray($res) {
133 | if ($res === null) {
134 | return false;
135 | }
136 |
137 | $f = array();
138 | while (true) {
139 | $row = $res->fetch_row();
140 | if ($row === null) {
141 | break;
142 | }
143 | array_push($f, $row[0]);
144 | }
145 |
146 | return $f;
147 | }
148 |
149 | public function lastError() {
150 | return self::$shared['error'];
151 | }
152 |
153 | public function getTable() {
154 | return $this->table;
155 | }
156 |
157 | public function getPrefix() {
158 | return self::$shared['prefix'];
159 | }
160 |
161 | protected static function init() {
162 | if (self::$shared !== null) {
163 | return;
164 | }
165 |
166 | global $ctx;
167 | $elems = $ctx->elems;
168 | $port = $elems->conf->mysql['port'];
169 | $conn = new \mysqli(
170 | "{$elems->conf->mysql['host']}" . (!empty($port) ? ":$port" : ""),
171 | $elems->conf->mysql['username'],
172 | $elems->conf->mysql['password']);
173 |
174 | self::$shared = array('conn' => $conn, 'prefix' => $elems->conf->mysql['prefix'], 'error' => null);
175 |
176 | if ($conn->connect_error) {
177 | self::$shared['error'] = "Mysql connection error {$conn->connect_errno}";
178 | return;
179 | }
180 |
181 | $conn->set_charset('utf8');
182 |
183 | $res = $conn->select_db($elems->conf->mysql['db']);
184 |
185 | if ($res === false) {
186 | self::$shared['error'] = 'Mysql database error';
187 | return;
188 | }
189 | }
190 |
191 | function __destruct() {
192 | if (self::$shared === null) {
193 | return;
194 | }
195 | self::$shared['conn']->close();
196 | self::$shared = null;
197 | }
198 |
199 | }
200 |
--------------------------------------------------------------------------------
/module/dao/TasksDao.php:
--------------------------------------------------------------------------------
1 | query('update ' . $this->getTable()
13 | . ' set solved = (select count(userid) from '
14 | . $this->getPrefix() . 'usertasks where solved > 0 and taskid = ' . $this->getTable() . '.id)');
15 | }
16 |
17 | function updateCosts() {
18 | $this->query('update ' . $this->getTable() . ' full join '
19 | . '(select max(solved) + 1 as maxsolved from ' . $this->getTable() . ') mx '
20 | . 'set cost = 1 + log10(maxsolved / (solved + 1)) * 4');
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/module/dao/UserDataDao.php:
--------------------------------------------------------------------------------
1 | query('select date(created) as thedate, count(userid) as cnt from '
13 | . $this->getTable() . " where solved > 0 and created > '$from' group by thedate order by thedate desc");
14 | return $this->objectsArray($res);
15 | }
16 |
17 | function updatePoints() {
18 | $this->query('update ' . $this->getTable() . ' join ' . $this->getPrefix() . 'userpoints using(userid) '
19 | . 'set points = sumcost');
20 | $this->query('update ' . $this->getTable() . ' set rankpos = '
21 | . '(select @idx := @idx + 1 from (select @idx := 0) s) '
22 | . 'order by points desc');
23 | }
24 |
25 | function languages() {
26 | $res = $this->query('select * from '
27 | . '(select language,count(1) as cnt from ' . $this->getTable() . ' group by language) '
28 | . 'subq order by cnt desc');
29 | return $this->objectsArray($res);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/module/dao/UserTasksDao.php:
--------------------------------------------------------------------------------
1 | query("select language, count(language) as cnt from "
13 | . $this->getTable() . " where userid = $userid group by language");
14 | return $this->objectsArray($res);
15 | }
16 |
17 | function solvingStats($from) {
18 | $res = $this->query('select date(ts) as thedate, count(id) as cnt from '
19 | . $this->getTable() . " where solved > 0 and ts > '$from' and variant = 0 group by thedate order by thedate desc");
20 | return $this->objectsArray($res);
21 | }
22 |
23 | function topOfWeek($limit) {
24 | $res = $this->query("select userid, count(taskid) as cnt from " . $this->getTable()
25 | . " where solved = 1 and variant = 0 and ts > now() - interval 7 day group by userid order by cnt desc limit $limit");
26 | return $this->objectsArray($res);
27 | }
28 |
29 | function searchSolution($taskid, $snippet, $count=20, $offset = 0) {
30 | $res = $this->query(
31 | "select url, language, length(s.solution) as len from {$this->getTable()} ut "
32 | . "join {$this->getPrefix()}solutions s on ut.id = s.usertaskid "
33 | . "join {$this->getPrefix()}users u on ut.userid = u.id "
34 | . "where taskid = $taskid and INSTR(FROM_BASE64(solution),
35 | '$snippet') limit $count offset $offset");
36 | return $this->objectsArray($res);
37 | }
38 |
39 | function solvers($criteria, $noblanks=true) {
40 | $res = $this->query(
41 | "select ut.id from {$this->getTable()} ut "
42 | . "join {$this->getPrefix()}solutions s on ut.id = s.usertaskid "
43 | . "where $criteria" . ($noblanks ? " and length(s.solution) > 13" : ""));
44 | return $this->singleFieldArray($res);
45 | }
46 |
47 | function languages() {
48 | $res = $this->query('select * from '
49 | . '(select language,count(1) as cnt from ' . $this->getTable() . ' where solved=1 group by language) '
50 | . 'subq order by cnt desc');
51 | return $this->objectsArray($res);
52 | }
53 |
54 | function lastSolved($userid) {
55 | $res = $this->query("select taskid, ts as ts "
56 | . "from {$this->getTable()} "
57 | . "where userid = $userid and solved=1 order by ts desc limit 1");
58 | if (!$res) {
59 | return [0, 0];
60 | }
61 | $res = $this->objectsArray($res);
62 | return [$res[0]->taskid, strtotime($res[0]->ts)];
63 | }
64 |
65 | function neverSolvedIds($userid) {
66 | $res = $this->query("select taskid from {$this->getTable()} "
67 | . "where userid=$userid group by taskid having max(solved)=-1");
68 | return $this->singleFieldArray($res);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/module/service/CertService.php:
--------------------------------------------------------------------------------
1 | ctx->challengesDao->getCount("taskid = $taskid and userid = 0") != 0;
11 | }
12 |
13 | function arenaExists($taskid) {
14 | $ch = $this->ctx->challengesDao->findFirst("taskid = {$taskid} and userid = 0");
15 | return is_object($ch) && preg_match('/\+arena$/', $ch->notes) > 0;
16 | }
17 |
18 | function processResult($taskid, $userid, $result) {
19 | $result = explode(' ', $result, 2);
20 | $score = (float) $result[0];
21 | $notes = $result[1];
22 | $this->updateResult($taskid, $userid, $score, $notes);
23 | $this->recalculate($taskid);
24 | }
25 |
26 | function updateResult($taskid, $userid, $score, $notes) {
27 | $ctx = $this->ctx;
28 | $chlng = $ctx->challengesDao->findFirst("taskid = $taskid and userid = $userid");
29 | if (!is_object($chlng)) {
30 | $chlng = new \stdClass();
31 | $chlng->taskid = $taskid;
32 | $chlng->userid = $userid;
33 | }
34 | $chlng->score = $score;
35 | $chlng->notes = $notes;
36 | $ctx->challengesDao->save($chlng);
37 | }
38 |
39 | function recalculate($taskid) {
40 | $ctx = $this->ctx;
41 | $stats = $this->loadAndSort($taskid);
42 | if (empty($stats)) {
43 | return;
44 | }
45 | $prev = INF;
46 | $count = -1;
47 | foreach ($stats as $entry) {
48 | $count++;
49 | if ($prev - $entry->score > $entry->score * 1e-6) {
50 | $prev = $entry->score;
51 | $curCount = $count;
52 | }
53 | $entry->total = $this->maxScore * exp(- $curCount / 16);
54 | $ctx->challengesDao->save($entry);
55 | }
56 | }
57 |
58 | function loadStats($taskid) {
59 | $ctx = $this->ctx;
60 | $stats = $this->loadAndSort($taskid);
61 | if (empty($stats)) {
62 | return $stats;
63 | }
64 | $userIds = $ctx->miscService->listIds($stats, 'userid');
65 | $users = $ctx->usersDao->makeLookup('id', "id in ($userIds)");
66 | foreach ($stats as $entry) {
67 | $user = $users[$entry->userid];
68 | $entry->username = $user->username;
69 | $entry->userurl = $user->url;
70 | }
71 | return $stats;
72 | }
73 |
74 | function loadAndSort($taskid) {
75 | $stats = $this->ctx->challengesDao->find("taskid = $taskid and userid <> 0");
76 | if (empty($stats)) {
77 | return $stats;
78 | }
79 | usort($stats, array('\module\service\ChallengeService', 'statsSort'));
80 | return $stats;
81 | }
82 |
83 | static function statsSort($a, $b) {
84 | if ($a->score > $b->score) {
85 | return -1;
86 | } else if ($a->score < $b->score) {
87 | return 1;
88 | }
89 | return 0;
90 | }
91 |
92 | }
93 |
94 |
--------------------------------------------------------------------------------
/module/service/CheatService.php:
--------------------------------------------------------------------------------
1 | status($userid)->suspended;
9 | }
10 |
11 | public function status($userid) {
12 | $res = new \stdClass();
13 | $res->score = 7;
14 | $res->suspended = false;
15 | $res->msg = '';
16 | $res->note = '';
17 | return $res;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/module/service/FriendService.php:
--------------------------------------------------------------------------------
1 | loadFriendship($userid, $targetid);
9 | if (!is_object($res)) {
10 | return 0;
11 | }
12 | return $res->visible ? 1 : -1;
13 | }
14 |
15 | private function loadFriendship($userid, $targetid) {
16 | return $this->ctx->friendsDao->findFirst("userid = $userid and targetid = $targetid");
17 | }
18 |
19 | function followedByCount($userid) {
20 | return $this->ctx->friendsDao->getCount("targetid = $userid");
21 | }
22 |
23 | function followingCount($userid) {
24 | return $this->ctx->friendsDao->getCount("userid = $userid");
25 | }
26 |
27 | function followedBy($userid) {
28 | $list = $this->ctx->friendsDao->find("targetid = $userid and visible <> 0");
29 | return $this->loadUsers($list, 'userid');
30 | }
31 |
32 | function following($userid) {
33 | $list = $this->ctx->friendsDao->find("userid = $userid and visible <> 0");
34 | return $this->loadUsers($list, 'targetid');
35 | }
36 |
37 | function followingAllIds($userid) {
38 | $list = $this->ctx->friendsDao->makeLookup('targetid', "userid = $userid");
39 | return array_keys($list);
40 | }
41 |
42 | private function loadUsers(&$records, $field) {
43 | $users = array();
44 | foreach ($records as $rec) {
45 | $users[] = $this->ctx->usersDao->read($rec->$field);
46 | }
47 | return $users;
48 | }
49 |
50 | function changeState($userid, $targetid, $secret) {
51 | $cur = $this->loadFriendship($userid, $targetid);
52 | if (is_object($cur)) {
53 | $this->ctx->friendsDao->delete($cur->id);
54 | } else {
55 | $f = new \stdClass();
56 | $f->userid = $userid;
57 | $f->targetid = $targetid;
58 | $f->visible = $secret ? 0 : 1;
59 | $this->ctx->friendsDao->save($f);
60 | }
61 | }
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/module/service/LangService.php:
--------------------------------------------------------------------------------
1 | \:\;\s]/', '', $s));
11 | if ($lenBf / ($len + 1) > 0.6 && strpos($s, '#include') === false) {
12 | return 'Brainfuck';
13 | }
14 | if (stripos($s, '<-') !== false) {
15 | return "R";
16 | }
17 | if (strpos($s, 'var ') !== false) {
18 | return strpos($s, 'using ') !== false ? "C#" : "JavaScript";
19 | }
20 | if (preg_match('/\bputs|gets\b/', $s) == 1
21 | && preg_match('/\b\.times|\.each\b/', $s) == 1) {
22 | return "Ruby";
23 | }
24 | if (preg_match('/with\s+ada/i', $s) == 1) {
25 | return "Ada";
26 | }
27 | if (preg_match('/fn\s+main/i', $s) == 1) {
28 | return "Rust";
29 | }
30 | $endMatches = array();
31 | $endlines = preg_match_all('/[\,\;\{][\040\t]*[\n\r]/', $s, $endMatches);
32 | if ($endlines / ($cnt[10] + 1) > 0.4) {
33 | if (strpos($s, '#include') !== false) {
34 | return "C/C++";
35 | }
36 | if (preg_match('/main\s*\(\s*String/', $s) == 1) {
37 | return "Java";
38 | }
39 | if ($cnt[ord('$')] / $len > 0.005) {
40 | return "PHP";
41 | }
42 | return "C#";
43 | } else {
44 | if (preg_match('/\([\+]/', $s) == 1) {
45 | return "LISP";
46 | }
47 | if (stripos($s, 'dim ') !== false) {
48 | return "VB";
49 | }
50 | if (stripos($s, 'local ') !== false) {
51 | return "Lua";
52 | }
53 | return "Python";
54 | }
55 | }
56 |
57 | function languagesArray() {
58 | return $this->ctx->elems->conf->languages;
59 | }
60 |
61 | function preferredLanguage($userid) {
62 | $table = $this->ctx->userTasksDao->languagesCount($userid);
63 | $res = '';
64 | $max = 0;
65 | foreach ($table as $t) {
66 | if ($t->cnt > $max) {
67 | $max = $t->cnt;
68 | $res = $t->language;
69 | }
70 | }
71 | return $res;
72 | }
73 |
74 | function preferredLanguageUpdate($userid) {
75 | $lang = $this->preferredLanguage($userid);
76 | $data = $this->ctx->userDataDao->findFirst("userid = $userid");
77 | $data->language = $lang;
78 | $this->ctx->userDataDao->save($data);
79 | return $lang;
80 | }
81 |
82 | function checkAndFixLanguage($language) {
83 | $languages = $this->languagesArray();
84 | if (isset($languages[$language])) {
85 | return $languages[$language];
86 | } else if (in_array($language, $languages)) {
87 | return $language;
88 | }
89 | return null;
90 | }
91 |
92 | function changeLanguage($task, $user, &$oldLang, &$language, $confirm, $model) {
93 | $language = $this->checkAndFixLanguage($language);
94 | $oldLang = $this->checkAndFixLanguage($oldLang);
95 | if ($oldLang === null || $language === null) {
96 | return array(0, "Unknown error");
97 | }
98 |
99 | $userTaskOld = $this->ctx->userTasksDao->findFirst("taskid = {$task->id} and userid = {$user->id} and language = '$oldLang'");
100 | $userTaskNew = $this->ctx->userTasksDao->findFirst("taskid = {$task->id} and userid = {$user->id} and language = '$language'");
101 | if (!is_object($userTaskOld)) {
102 | return array(0, 'Solution missed');
103 | }
104 |
105 | if ($confirm) {
106 | $this->doChangeLanguage($userTaskOld, $userTaskNew, $task->url, $user->url, $language);
107 | return array(2, 'Language successfully changed');
108 | } else {
109 | $this->prepareConfirmation($task, $user, $oldLang, $language, is_object($userTaskNew), $model);
110 | return array(1);
111 | }
112 | }
113 |
114 | private function doChangeLanguage($userTaskOld, $userTaskNew, $taskurl, $userurl, $language) {
115 | $ctx = $this->ctx;
116 | if (is_object($userTaskNew)) {
117 | $userTaskOld->solved = max($userTaskNew->solved, $userTaskOld->solved);
118 | $userTaskOld->variant = min($userTaskNew->variant, $userTaskOld->variant);
119 | }
120 | $userTaskOld->language = $language;
121 | $ctx->userTasksDao->save($userTaskOld);
122 | if (is_object($userTaskNew)) {
123 | $this->deleteDuplicateSolution($userTaskOld, $userTaskNew);
124 | }
125 | }
126 |
127 | private function deleteDuplicateSolution($userTaskOld, $userTaskNew) {
128 | $ctx = $this->ctx;
129 | $votes = $ctx->codelikesDao->find("codeid = {$userTaskNew->id}");
130 | foreach ($votes as $vote) {
131 | $vote->codeid = $userTaskOld->id;
132 | $ctx->codelikesDao->save($vote);
133 | }
134 | $ctx->userTasksDao->delete($userTaskNew->id);
135 | }
136 |
137 | private function prepareConfirmation($task, $user, $oldlang, $language, $overwrite, $model) {
138 | $model->task = $task;
139 | $model->username = $user->username;
140 | $model->userurl = $user->url;
141 | $model->oldlang = $oldlang;
142 | $model->newlang = $language;
143 | $model->overwrite = $overwrite;
144 | $model->backurl = url('task_solution', 'task', $task->url, 'user', $user->url, 'lang', urlencode($oldlang));
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/module/service/LocaleService.php:
--------------------------------------------------------------------------------
1 | LOCALES_ARRAY = array('ar' => 'Arabic', 'es' => 'Spanish',
11 | 'fr' => 'French', 'de' => 'German', 'ro' => 'Romanian',
12 | 'ru' => 'Russian', 'sk' => 'Slovak', 'zh' => 'Chinese',
13 | 'ua' => 'Ukrainian');
14 | }
15 |
16 | function parseLocale($url) {
17 | if (strpos($url, '--') == false) {
18 | return array($url, '');
19 | }
20 | $res = explode('--', $url, 2);
21 | if (!in_array($res[1], array_keys($this->LOCALES_ARRAY))) {
22 | $res[0] = '';
23 | }
24 | return $res;
25 | }
26 |
27 | public function availableTaskLocales($id) {
28 | $loc = $this->ctx->miscService->getTaggedValue("tran-$id");
29 | if (empty($loc)) {
30 | return array();
31 | }
32 | $ava = $this->LOCALES_ARRAY;
33 | $loc = explode(' ', $loc);
34 | $res = array();
35 | foreach ($loc as $k) {
36 | if (isset($ava[$k])) {
37 | $res[$k] = $ava[$k];
38 | }
39 | }
40 | return $res;
41 | }
42 |
43 | public function direction($locale) {
44 | return $locale != 'ar' ? 'ltr' : 'rtl';
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/module/service/LoginService.php:
--------------------------------------------------------------------------------
1 | ctx;
9 | if ($hashed) {
10 | $password = $this->hashPassword($password);
11 | }
12 | $ctx->auth->login($username, $password);
13 | $userid = $ctx->auth->loggedUser();
14 | if (!$userid) {
15 | return null;
16 | }
17 | if ($ctx->auth->user()) {
18 | $this->afterLogin($userid, $username);
19 | }
20 | return $userid;
21 | }
22 |
23 | function afterLogin($userid, $username) {
24 | $ctx = $this->ctx;
25 | $userdata = $ctx->userDataDao->findFirst("userid = $userid");
26 | $userdata->lastlogin = date('Y-m-d H:i:s');
27 | $remoteAddress = $this->remoteAddress();
28 | $country = $this->detectCountry($remoteAddress);
29 | $ctx->util->sessionPut('country', $country);
30 | if (empty($userdata->country)) {
31 | $userdata->country = $country;
32 | }
33 | $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
34 | $ctx->userDataDao->save($userdata);
35 | $ctx->miscService->logAction($userid, "login $remoteAddress $country $lang");
36 | $ctx->miscService->postToMessHall($userid, "I've just logged in...");
37 | $ctx->msgService->loadNotifications($userid);
38 | }
39 |
40 | function remoteAddress() {
41 | if(!empty($_SERVER['REMOTE_ADDR']) ){
42 | return $_SERVER['REMOTE_ADDR'];
43 | }
44 | if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
45 | return $_SERVER['HTTP_X_FORWARDED_FOR'];
46 | }
47 | return '';
48 | }
49 |
50 | function detectCountry($ip) {
51 | $ip = trim($ip);
52 | $lines = file_get_contents('./data/db-ip.txt');
53 | if (!preg_match('/\d+\.\d+\.\d+\.\d+/', $ip) || $lines === false) {
54 | return 'ZZ';
55 | }
56 | $ip = explode('.', $ip);
57 | $res = 0;
58 | foreach ($ip as $d) {
59 | $res = $res * 256 + $d;
60 | }
61 | $lines = explode("\n", $lines);
62 | $min = 0;
63 | $max = count($lines) - 1;
64 | while ($min < $max) {
65 | $mid = floor(($min + $max + 1) / 2);
66 | $line = explode(' ', $lines[$mid]);
67 | $start = floatval(base_convert($line[0], 36, 10));
68 | if ($start > $res) {
69 | $max = $mid - 1;
70 | } else {
71 | $min = $mid;
72 | }
73 | }
74 | $line = explode(' ', $lines[$min]);
75 | $from = floatval(base_convert($line[0], 36, 10));
76 | $till = $from + floatval(base_convert($line[1], 36, 10));
77 | return ($res >= $from && $res <= $till) ? $line[2] : 'ZZ';
78 | }
79 |
80 | function githubLoginUrl() {
81 | return '#';
82 | }
83 |
84 | function googleLoginUrl() {
85 | return '#';
86 | }
87 |
88 | function hashPassword($pwd) {
89 | return base64_encode(hash('sha512', $this->ctx->elems->conf->passwordSalt . $pwd, true));
90 | }
91 |
92 | function hashEmail($email) {
93 | $email = strtolower($email);
94 | $h = base64_encode(hash('sha512', $this->ctx->elems->conf->emailSalt . $email, true));
95 | $tail = preg_replace('/^[^\@]+/', '', $email);
96 | return $email[0] . '*' . substr($h, 0, 8) . $tail;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/module/service/MiscService.php:
--------------------------------------------------------------------------------
1 | ctx->countriesDao->findFirst("code = '$code'");
12 | if (is_object($country)) {
13 | return $country->title;
14 | }
15 | return null;
16 | }
17 |
18 | function curTimeStr() {
19 | return date('Y-m-d H:i:s');
20 | }
21 |
22 | function formatDate($ts, $withTime = false) {
23 | if (gettype($ts) == 'string') {
24 | $ts = strtotime($ts);
25 | }
26 | return date($withTime ? 'M j Y H:i' : 'M j Y', $ts);
27 | }
28 |
29 | function formatTitle() {
30 | if (empty($this->ctx->elems->title)) {
31 | return $this->ctx->elems->conf->title;
32 | }
33 |
34 | return "{$this->ctx->elems->title} - {$this->ctx->elems->conf->projectName}";
35 | }
36 |
37 | function formatDescription() {
38 | if (!empty($this->ctx->elems->description)) {
39 | return $this->ctx->elems->description;
40 | }
41 | if (empty($this->ctx->elems->title)) {
42 | return $this->ctx->elems->conf->descr;
43 | }
44 | $title = preg_replace('/[\"\&]/', '', $this->ctx->elems->title);
45 | return "$title - {$this->ctx->elems->conf->descrSuffix}";
46 | }
47 |
48 | function headerLastModified($timestamp) {
49 | $time = strtotime($timestamp);
50 | $twoWeeksAgo = time() - 86400 * 14;
51 | $time = max($time, $twoWeeksAgo);
52 | header('Last-Modified: ' . date("D, d M Y H:i:s", $time) . ' GMT');
53 | }
54 |
55 | function postToMessHall($userid, $message) {
56 | $record = new \stdClass();
57 | $record->userid = $userid;
58 | $record->created = date('Y-m-d H:i:s');
59 | $record->message = base64_encode($message);
60 | $this->ctx->chatDao->save($record);
61 | }
62 |
63 | function logAction($userid, $message) {
64 | $date = date('Ymd-His');
65 | if (!empty($userid)) {
66 | $user = $this->ctx->usersDao->read($userid);
67 | $url = $user->url;
68 | } else {
69 | $url = '-null-';
70 | }
71 | $logName = $this->ctx->elems->conf->logging['activity'] ?? false;
72 | if ($logName)
73 | error_log("$date $url $message\n", 3, $logName);
74 | }
75 |
76 | function summarize(&$arr, $field) {
77 | $res = array();
78 | foreach ($arr as $elem) {
79 | $idx = $elem->$field;
80 | if (!isset($res[$idx])) {
81 | $res[$idx] = 1;
82 | } else {
83 | $res[$idx]++;
84 | }
85 | }
86 | return $res;
87 | }
88 |
89 | function listIds(&$arr, $field, $imploded = true) {
90 | $res = $this->summarize($arr, $field);
91 | $res = array_keys($res);
92 | if ($imploded) {
93 | $res = implode(',', $res);
94 | }
95 | return $res;
96 | }
97 |
98 | function validUrlParam($url) {
99 | return $url === null || preg_match('/^[a-z0-9\-\_]+$/', $url);
100 | }
101 |
102 | function validUrlParams() {
103 | $args = func_get_args();
104 | foreach ($args as $a) {
105 | if (!$a || !$this->validUrlParam($a)) {
106 | return false;
107 | }
108 | }
109 | return true;
110 | }
111 |
112 | function encryptInt($value) {
113 | return sprintf("%12d", $value);
114 | }
115 |
116 | function decryptInt($cipher) {
117 | return intval($cipher);
118 | }
119 |
120 | function setTaggedValue($tag, $val) {
121 | $record = $this->ctx->tagValDao->findFirst("tag = '$tag'");
122 | if (!is_object($record)) {
123 | $record = new \stdClass();
124 | $record->tag = $tag;
125 | } else if ($val === null) {
126 | $this->ctx->tagValDao->delete($record->id);
127 | return;
128 | }
129 | $record->val = base64_encode(serialize($val));
130 | $this->ctx->tagValDao->save($record);
131 | }
132 |
133 | function getTaggedValue($tag) {
134 | $record = $this->ctx->tagValDao->findFirst("tag = '$tag'");
135 | if (!is_object($record)) {
136 | return null;
137 | }
138 | return unserialize(base64_decode($record->val));
139 | }
140 |
141 | function getTaggedValues($prefix) {
142 | $records = $this->ctx->tagValDao->find("tag like '$prefix%'");
143 | $res = array();
144 | foreach ($records as $rec) {
145 | $res[$rec->tag] = unserialize(base64_decode($rec->val));
146 | }
147 | return $res;
148 | }
149 |
150 | function isMobile() {
151 | $aMobileUA = array('/iphone/i' => 'iPhone', '/ipod/i' => 'iPod', '/ipad/i' => 'iPad',
152 | '/android/i' => 'Android', '/blackberry/i' => 'BlackBerry', '/webos/i' => 'Mobile');
153 | foreach($aMobileUA as $sMobileKey => $sMobileOS){
154 | if(preg_match($sMobileKey, $_SERVER['HTTP_USER_AGENT'])){
155 | return true;
156 | }
157 | }
158 | return false;
159 | }
160 |
161 | function calcPoints() {
162 | $this->ctx->tasksDao->updateCosts();
163 | $tasks = $this->ctx->tasksDao->makeLookup();
164 |
165 | $res = [];
166 | foreach ($tasks as $t) {
167 | if ($this->ctx->challengeService->challengeExists($t->id)) {
168 | $this->ctx->challengeService->recalculate($t->id);
169 | }
170 | $res[] = "{$t->title}: {$t->cost}\n";
171 | }
172 |
173 | $this->ctx->userDataDao->updatePoints();
174 |
175 | return $res;
176 | }
177 |
178 | }
179 |
180 |
--------------------------------------------------------------------------------
/module/service/MsgService.php:
--------------------------------------------------------------------------------
1 | ctx;
9 | $msg = $this->loadPersonal($userid);
10 | if (!empty($msg)) {
11 | $ctx->util->sessionPut('message-personal', $msg);
12 | }
13 | }
14 |
15 | function loadPersonal($userid) {
16 | return $this->ctx->miscService->getTaggedValue("msg-$userid");
17 | }
18 |
19 | function setPersonal($userUrl, $msg) {
20 | $ctx = $this->ctx;
21 | $user = $ctx->usersDao->findFirst("url = '$userUrl'");
22 | if (is_object($user)) {
23 | $ctx->util->flash('Message set for ' . $user->url);
24 | $ctx->miscService->setTaggedValue("msg-{$user->id}", empty($msg) ? null : $msg);
25 | } else {
26 | $ctx->util->flash('User not found: ' . $userUrl);
27 | }
28 | }
29 |
30 | function clearPersonal() {
31 | $ctx = $this->ctx;
32 | $userId = $ctx->auth->loggedUser();
33 | $ctx->miscService->setTaggedValue("msg-$userId", null);
34 | $this->ctx->util->sessionDel('message-personal');
35 | }
36 |
37 | function getMessagePersonal() {
38 | $delta = time() - $this->ctx->util->sessionGet('message-personal-ts') ?? 0;
39 | if ($delta > 180) {
40 | $msg = $this->ctx->miscService->getTaggedValue('msg-' . $this->ctx->auth->loggedUser());
41 | if (!empty($msg)) {
42 | $this->ctx->util->sessionPut('message-personal-ts', time());
43 | $this->ctx->util->sessionPut('message-personal', $msg);
44 | }
45 | }
46 | return $this->ctx->util->sessionGet('message-personal');
47 | }
48 |
49 | function getAllPersonal() {
50 | $ctx = $this->ctx;
51 | $records = $ctx->tagValDao->find("tag like 'msg-%'");
52 | $users = array();
53 | foreach ($records as $rec) {
54 | $userid = substr($rec->tag, 4);
55 | $user = $ctx->usersDao->read($userid);
56 | $users[$user->id] = $user->username;
57 | }
58 | return $users;
59 | }
60 |
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/module/service/StrUtils.php:
--------------------------------------------------------------------------------
1 | layout = 'default_bs';
22 | $this->styles = [];
23 | $this->scripts = [];
24 | $this->conf = new \stdClass();
25 | $this->conf->custFrag = [];
26 | $this->conf->custSvc = [];
27 | $this->conf->logging = [];
28 | $this->modules = array();
29 | $this->moduleOrder = array();
30 | $this->errors = array();
31 | self::$elems = $this;
32 | }
33 |
34 | function get($field, $default = '') {
35 | if (isset($this->$field)) {
36 | return $this->$field;
37 | }
38 | return $default;
39 | }
40 |
41 | function addError($e) {
42 | array_push($this->errors, $e);
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/module/sys/ProtoContext.php:
--------------------------------------------------------------------------------
1 | $methodName();
11 | } else {
12 | if (substr($name, -7) == 'Service') {
13 | $name = ucfirst($name);
14 | $name = $this->elems->conf->custSvc[$name] ?? $name;
15 | $fullname = "\\module\\service\\$name";
16 | $res = new $fullname();
17 | } elseif (substr($name, -3) == 'Dao') {
18 | $res = new \module\dao\MysqlDao(strtolower(substr($name, 0, -3)));
19 | } else {
20 | $fullname = "\\module\\lib\\" . ucfirst($name);
21 | $res = new $fullname();
22 | }
23 | }
24 | if (is_object($res)) {
25 | $res->ctx = $this;
26 | }
27 | $this->$name = $res;
28 | return $res;
29 | }
30 |
31 | protected function getElems() {
32 | return \module\sys\Elems::$elems;
33 | }
34 |
35 | protected function getUtil() {
36 | return new \module\sys\Util();
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/module/sys/Util.php:
--------------------------------------------------------------------------------
1 | sessionPrepare();
11 | $_SESSION[$key] = $value;
12 | }
13 |
14 | function sessionDel($key) {
15 | $this->sessionPrepare();
16 | unset($_SESSION[$key]);
17 | }
18 |
19 | function sessionGet($key) {
20 | $this->sessionPrepare();
21 | if (!isset($_SESSION[$key])) {
22 | return null;
23 | }
24 | return $_SESSION[$key];
25 | }
26 |
27 | private function sessionPrepare() {
28 | if (!$this->sessionStarted) {
29 | ini_set('session.gc_maxlifetime', 6 * 3600);
30 | session_start();
31 | $this->sessionStarted = true;
32 | }
33 | }
34 |
35 | function flash($msg = null) {
36 | if ($msg !== null) {
37 | $this->sessionPut('__flash_msg', $msg);
38 | } else {
39 | $res = $this->sessionGet('__flash_msg');
40 | $this->sessionDel('__flash_msg');
41 | return $res;
42 | }
43 | }
44 |
45 | function fullUrl($url, $prefix = 'http://') {
46 | if (strpos($url, '/') === false) {
47 | $url = url($url);
48 | }
49 | return $prefix . $_SERVER['HTTP_HOST'] . $url;
50 | }
51 |
52 | function sendGetRequest($url, $timeout = 3) {
53 | $context = stream_context_create(array('http' => array('timeout' => $timeout)));
54 | return file_get_contents($url, false, $context);
55 | }
56 |
57 | function sendPostRequest($url, $data, $timeout = 3, &$responseHeaders = null) {
58 | $context = stream_context_create(array('http' => array(
59 | 'header' => "Content-type: application/x-www-form-urlencoded",
60 | 'method' => 'POST',
61 | 'content' => !is_string($data) ? http_build_query($data) : $data,
62 | 'timeout' => $timeout
63 | )));
64 | $res = file_get_contents($url, false, $context);
65 | if ($responseHeaders !== null) {
66 | $responseHeaders = $http_response_header;
67 | }
68 | return $res;
69 | }
70 |
71 | function redirect($url) {
72 | if (strpos($url, '/') === false) {
73 | $url = url($url);
74 | }
75 | header("Location: $url");
76 | $this->changePage(null);
77 | }
78 |
79 | function paramGet($name) {
80 | if (!isset($_GET[$name])) {
81 | return null;
82 | }
83 | return $_GET[$name];
84 | }
85 |
86 | function paramPost($name) {
87 | if (!isset($_POST[$name])) {
88 | return null;
89 | }
90 | return $_POST[$name];
91 | }
92 |
93 | function fragment($name) {
94 | $name = $this->ctx->elems->conf->custFrag[$name] ?? $name;
95 | if ($name === '') {
96 | return;
97 | }
98 | $name = str_replace('_', '/', $name);
99 | if (!addfile('fragments/' . $name . '.html')) {
100 | echo '??? FRAGMENT: ' . $name . ' ???';
101 | }
102 | }
103 |
104 | function changePage($name) {
105 | $this->ctx->elems->page = str_replace('_', '/', $name ?? '');
106 | }
107 |
108 | function plainOutput($data, $type = 'text/plain') {
109 | $this->changePage(null);
110 | header("Content-Type: $type");
111 | echo $data;
112 | }
113 |
114 | function sillyDecode($s) {
115 | $hiCode = ord('p');
116 | $loCode = ord('k');
117 | $n = strlen($s);
118 | $res = array();
119 | for ($i = 0; $i < $n; $i += 2) {
120 | $res[] = chr(($hiCode - ord($s[$i])) * 16 + (ord($s[$i + 1]) - $loCode));
121 | }
122 | return implode('', $res);
123 | }
124 |
125 | function runScript($cmd, $input, &$output, &$stderr = null) {
126 | $dsc = array(
127 | array('pipe', 'r'),
128 | array('pipe', 'w'),
129 | array('pipe', 'w'));
130 | $pipes = array();
131 | $ps = proc_open($cmd, $dsc, $pipes);
132 | if (!is_resource($ps)) {
133 | return -1;
134 | }
135 | fwrite($pipes[0], $input);
136 | fclose($pipes[0]);
137 | $output = stream_get_contents($pipes[1]);
138 | fclose($pipes[1]);
139 | $err = stream_get_contents($pipes[2]);
140 | fclose($pipes[2]);
141 | if ($stderr !== null) {
142 | $stderr = $err;
143 | }
144 | return proc_close($ps);
145 | }
146 |
147 | function runSqlite($input) {
148 | return $this->sendPostRequest(
149 | 'http://rodiongork.freeshell.org/sqlrun.cgi', $input, 5);
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/pages/.htaccess:
--------------------------------------------------------------------------------
1 | Order deny,allow
2 | Deny from all
3 |
--------------------------------------------------------------------------------
/pages/error.php:
--------------------------------------------------------------------------------
1 | Error
2 |
3 | Excuse us, some error have happened.
4 |
--------------------------------------------------------------------------------
/pages/error403.php:
--------------------------------------------------------------------------------
1 |
4 | Access denied
5 | Excuse us, you have not access rights for this page.
6 |
--------------------------------------------------------------------------------
/pages/error404.php:
--------------------------------------------------------------------------------
1 |
4 | Page not found
5 | Excuse us, but there is no such page.
6 |
--------------------------------------------------------------------------------
/pages/forum/edit.php:
--------------------------------------------------------------------------------
1 | Edit forum post
2 |
3 | = $ctx->util->fragment('forumform') ?>
4 |
5 |
--------------------------------------------------------------------------------
/pages/forum/list.php:
--------------------------------------------------------------------------------
1 | List of forums
2 |
3 | Currently under construction
4 |
5 | General Discussions
6 |
7 |
--------------------------------------------------------------------------------
/pages/forum/main.php:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
Branches
13 |
14 | forums as $forum) : ?>
15 |
16 |
17 | = $forum->info ?>
18 |
19 |
20 |
21 |
22 |
23 |
24 |
Recent
25 |
26 | topics as $topic) : ?>
27 |
28 |
31 |
38 |
39 | posts: = $topic->posts ?>, last at = $topic->lastpost ?>
40 |
41 |
42 | author: = $topic->user->username ?>
43 |
44 |
45 | last: = $topic->lastUser->username ?>
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/pages/forum/newtopic.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | = $ctx->util->fragment('forumform') ?>
4 |
5 |
--------------------------------------------------------------------------------
/pages/forum/noaccess.php:
--------------------------------------------------------------------------------
1 | Sorry!
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/pages/forum/topic.php:
--------------------------------------------------------------------------------
1 |
7 |
8 | forTask)) : ?>
9 | This topic is private for problem
10 | = $model->forTask->title ?>
11 |
12 |
13 |
14 | Back to = $model->forum->title ?> forum
15 |
16 | auth->admin()) : ?>
17 |
24 |
25 |
26 | posts as $post) : ?>
27 | lastPost) ? 'id="lastPost"' : ''?>>
28 |
29 |
37 | user->avatar != '') : ?>
38 |
39 |
40 | = $post->post ?>
41 |
42 |
43 |
44 |
45 | showForm) : ?>
46 | = $ctx->util->fragment('forumform') ?>
47 |
53 |
54 |
55 | Please login and solve 5 problems to be able to post at forum
56 |
57 |
--------------------------------------------------------------------------------
/pages/forum/view.php:
--------------------------------------------------------------------------------
1 |
7 |
8 | otherForums) : ?>
9 | Switch to forum:
10 | otherForums as $other) : ?>
11 | = $other->title ?>
12 |
13 |
14 |
15 | Write what's on your mind: tell about yourself, ask about the problem,
16 | request certificate etc!
17 |
18 |
19 | = $model->forum->info ?>
20 |
21 | showCreateLink) : ?>
22 |
23 |
25 | Create new topic
26 |
27 | Creating new topics is allowed after you solve at least 5 problems!
28 |
29 |
30 |
31 |
32 | Topic
33 | Posts
34 | Created
35 | Last post
36 |
37 | topics as $topic) : ?>
38 |
39 |
40 |
41 | = $topic->title ?>
42 | = $topic->posts ?>
43 | = $topic->user->username ?>
44 | = $topic->created ?>
45 | = $topic->lastUser->username ?>
46 | = $topic->lastpost ?>
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/pages/login.php:
--------------------------------------------------------------------------------
1 | Greetings
2 |
3 | logged) : ?>
4 | You logged in successfully, thank you!
5 |
6 |
7 | Please enter your credentials:
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 | *
17 | Only Latin letters
18 | and probably one underscore ,
19 | from 8 to 15 characters (i.e. "john_smirnoff")
20 |
21 | * Visible name can be changed on reaching level "Bishop"
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 | *
31 | Latin letters and digits
32 | (at least one of both)
33 | 8 characters or longer
34 | (i.e. "bzfra3jop", dashes, dots and underscores are OK)
35 |
36 |
37 |
38 |
39 |
Password forgotten? If your e-mail is still accessible,
40 | then recovery page may help...
41 |
42 |
43 |
44 |
45 |
46 | To register please fill also these fields:
47 |
49 |
51 |
52 |
53 |
54 |
55 |
Reminder: We don't store passwords and emails!
56 | We keep only their
hashes
, so that evil doers could not steal passwords or emails from database
57 | even if it is hacked.
58 | Read more in our
Privacy Policy .
59 |
60 | But anyway it is good to avoid using the
61 | same password for your important email and bank accounts. Choose some different.
62 |
63 |
We do not send you any emails! and don't require email confirmation.
64 | You will need it, however, if you forget your password - you'll be asked to type the same
65 | address to receive recovery letter.
66 |
67 | You may prefer login via
GitHub
/
Facebook
/
Gmail
- in this case we
68 | don't need to store password or email at all.
69 | Check login buttons at
main page .
70 |
71 |
72 |
73 |
74 |
75 | = $ctx->util->fragment('loginbuttons') ?>
76 |
77 |
78 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/pages/main.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
= $ctx->elems->conf->motto ?>
4 | = $ctx->util->fragment('main_image') ?>
5 |
6 | = $ctx->util->fragment('main_login') ?>
7 |
8 |
9 | = $ctx->util->fragment('main_middlenote') ?>
10 | = $ctx->util->fragment('main_lasttasks') ?>
11 | = $ctx->util->fragment('main_bottomnote') ?>
12 |
13 |
14 |
15 | = $ctx->util->fragment('main_login') ?>
16 | = $ctx->util->fragment('main_rank') ?>
17 | = $ctx->util->fragment('main_lastforum') ?>
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/pages/mess/hall.php:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
Here you can see what is going on at = $ctx->elems->conf->projectName ?>
12 |
13 |
14 |
15 | records as $rec) : ?>
16 |
17 | = $rec->created ?>
18 |
19 | avatar != '') : ?>
20 |
21 |
22 |
23 |
24 |
25 |
26 | = $rec->rank ?>
27 | = $rec->message ?>
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
Weekly stats
36 |
37 |
38 |
39 | Date
40 | Solved
41 |
42 | stats as $st) : ?>
43 |
44 | = $st->thedate ?>
45 | = $st->cnt ?>
46 |
47 |
48 | statsAvg)) : ?>
49 |
50 | Avg15
51 | = $model->statsAvg ?>
52 |
53 |
54 |
55 |
56 |
57 |
62 |
--------------------------------------------------------------------------------
/pages/message.php:
--------------------------------------------------------------------------------
1 |
Warning!
2 |
3 |
= $model->msg ?>
--------------------------------------------------------------------------------
/pages/task/edit.php:
--------------------------------------------------------------------------------
1 |
= $model->task->id ? "Edit Task #{$model->task->id}" : "Create New task" ?>
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Task Title:
10 |
11 |
12 | Url:
13 |
14 |
15 | Author:
16 |
17 |
18 | task->shown ? 'checked="true"' : ''?>/>Is Visible
19 |
20 | Problem Statement:
21 | = $model->task->text ?>
22 |
23 | Checker Code:
24 | = $model->task->checker ?>
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/pages/task/list.php:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 | addingAllowed) : ?>
17 |
Add new task
18 |
19 | filterTag)) : ?>
20 |
Volume :
21 |
22 | elems->conf->taskVolumes as $tag => $volume) : ?>
23 |
= $volume ?>
25 |
26 |
27 |
28 |
all tags
30 |
31 | volume !== null) : ?>
32 | Volume:
= $model->volume ?>
33 |
34 | Tagged with:
= $model->filterTag ?>
35 |
36 | - total = count($model->tasks) ?>
37 |
38 |
(clear filter)
39 |
40 |
41 |
42 |
43 | Trending and Bookmarked
44 | Sort by Num of Solvers
45 | Sort by Creation Order
46 | by Solvers (with solved)
47 | by Creation (with solved)
48 |
49 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | Id
64 | Title
65 | Translations
66 | Author
67 | Solved
68 | Blessing
69 | = $model->isUser ? 'Status ' : '' ?>
70 |
71 | tasks as $task) {
73 | $state = $task->state;
74 | $statusCell = $model->isUser ? "$state " : '';
75 | $editLink = $model->addingAllowed ? " editurl}\">edit " : '';
76 | $authorLink = $task->author
77 | ? '{$task->author} "
78 | : '';
79 | $solved = $task->solved;
80 | if ($state === 'solved' || ($model->addingAllowed && is_numeric($solved))) {
81 | $solved = '$solved - view ";
82 | }
83 | $isc1 = isset($model->c1ids[$task->id]) ? 'class="strong"' : '';
84 | if (isset($task->starred)) $isc1 .= ' style="background:gold"';
85 | echo "{$task->id} url}\">{$task->title} $editLink ";
86 | echo "{$task->translations} ";
87 | echo "$authorLink ";
88 | echo "$solved {$task->cost} $statusCell ";
89 | }
90 | ?>
91 |
92 |
93 |
--------------------------------------------------------------------------------
/pages/task/solution.php:
--------------------------------------------------------------------------------
1 |
36 |
37 | solution->error) : ?>
38 |
39 | highlight != 'other'): ?>
40 |
41 |
42 |
43 |
= $model->solution->code ?>
44 |
45 |
Length: = strlen($model->solution->code) ?>
46 |
47 |
48 | auth->admin()) : ?>
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
Error: = $model->solution->error ?>
58 |
59 |
--------------------------------------------------------------------------------
/pages/task/solvers.php:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
25 |
26 |
Notes on the problem
27 | = !empty($model->notes) ? $model->notes : 'Sorry, no editorial on this task is yet prepared...' ?>
28 |
29 |
30 |
31 |
parameters 'withblanks' and 'limit' may be useful
32 |
33 |
--------------------------------------------------------------------------------
/pages/task/success.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
Your answer is Correct !
8 |
9 |
10 |
11 | You now are allowed to see
12 |
other's solutions
13 | of this task!
14 | You received
= $model->gainedPoints ?> points of Blessing!
15 | Your
Enlightenment is now
16 |
= $model->userPoints ?>
17 |
(these values are approximate - exact ones will be known in few minutes -
18 | after total recalculation)
19 | nextTasks) > 0) : ?>
20 |
Suggested next tasks:
21 | nextTasks as $next) :
22 | $nextUrl = url('task_view', 'param', $next->url);
23 | echo "
{$next->title} ";
25 | endforeach;
26 | endif; ?>
27 |
28 | challengeResult)) : ?>
29 |
30 |
Challenge result:
31 |
32 | Score: = $model->challengeResult[1] ?>
33 |
34 | Notes: = $model->challengeResult[2] ?>
35 |
36 | view full stats
37 |
38 |
39 |
40 |
41 |
42 |
43 | this pane is under development
44 |
45 |
46 |
47 |
48 | Back to task list
49 |
50 |
51 |
Visit Our Forum if you have any questions or
52 | suggestions about problem statement or suspect the checker is incorrect.
53 |
54 |
55 |
56 |
Author's notes on this problem
57 |
58 |
= !empty($model->notes) ? $model->notes : 'Sorry, no notes were added yet for this task...' ?>
59 |
60 |
61 |
--------------------------------------------------------------------------------
/pages/task/tag/edit.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Available Tags
4 |
5 |
6 | tags as $tag) : ?>
7 | = $tag->title ?>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
new name to add or existing to remove (type in and press enter)
17 |
18 |
19 |
20 |
21 | task)) : ?>
22 |
= $model->task->title ?>
23 |
24 |
25 | taskTags as $tag) : ?>
26 | = $tag ?>
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
new tag to add or existing to remove (type in and press enter)
35 |
36 |
37 |
No task chosen :(
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/pages/task/tag/list.php:
--------------------------------------------------------------------------------
1 |
Tags for Problems
2 |
3 |
15 |
16 |
19 |
--------------------------------------------------------------------------------
/pages/task/view.php:
--------------------------------------------------------------------------------
1 |
60 |
61 |
62 | task->locales)) : ?>
63 | task->locales['en'])) : ?>
64 | Also available in:
65 | task->locales as $locale => $locName) : ?>
66 |
= $locName ?>
67 |
68 |
69 | Back to
English version
70 |
71 |
72 |
No translations... yet
73 |
74 | auth->user()) : ?>
75 |
report typos
76 |
77 |
78 |
79 |
80 | checkerCode)) : ?>
81 |
82 |
Looks like you invented this problem!
84 | Click to review the "checker" code...
85 |
Notes
86 |
= $model->checkerCode ?>
87 |
88 |
89 |
90 |
= $model->task->statement ?>
91 |
92 | auth->user()) : ?>
93 |
You need to
login to get test data and submit solution.
94 | solveUnsolved)) : ?>
95 |
96 |
97 |
You have too many unsolved tasks!
98 | According to rule 177.b you can't solve new problems until you solve
99 | some of tasks submitted unsuccessfully. Please visit your
100 |
101 | unsolved task list
102 | and try solving any of the tasks
marked red !
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | Test data: copy and paste them as an input for your program
112 |
113 |
114 | Your answer: paste here an answer from your program
115 |
116 |
117 | = $ctx->util->fragment('taskview_solcaption') ?>
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | suspended) : ?>
127 |
128 |
129 | Sorry, account is suspended for investigation and submissions are not allowed temporarily.
130 |
131 |
132 |
133 | = $ctx->util->fragment('taskview_runtools') ?>
134 |
135 |
136 |
137 | = $ctx->util->fragment('taskview_badattempt') ?>
138 |
139 | = $ctx->util->fragment('taskview_errorsmodal') ?>
140 |
141 |
142 |
143 |
= $model->task->lastmod ?>
144 |
--------------------------------------------------------------------------------
/pages/user/ranking.php:
--------------------------------------------------------------------------------
1 |
7 |
8 |
Select
your country in
9 | auth->loggedUser()) : ?>
10 |
your settings page
11 |
12 |
your profile
13 |
14 | and raise your flag in this table by solving problems!
15 |
16 |
17 |
18 | Total Brethren and Sistren (who solved at least one problem): = $model->total ?>
19 |
20 |
21 |
22 | friends === null) : ?>
23 |
24 |
25 | = $ctx->util->fragment('countryselect') ?>
26 | = $ctx->util->fragment('langselect') ?>
27 |
28 | clear
29 |
30 | userid)) : ?>
31 |
32 | View Friends
33 |
34 |
35 |
36 |
37 |
56 |
57 |
58 |
61 |
62 |
63 |
64 |
65 |
66 | #
67 | User
68 | Language
69 | Rank ?
70 | Enlightenment
71 |
72 | Solved
73 |
74 | myRank !== null && $model->myRank->before) :
75 | $model->curEntry = $model->myRank; ?>
76 | = $ctx->util->fragment('rankline') ?>
77 | ... ...
78 |
79 | rank as $rankLine) :
80 | $model->curEntry = $rankLine; ?>
81 | = $ctx->util->fragment('rankline') ?>
82 |
83 | myRank !== null && !$model->myRank->before) :
84 | $model->curEntry = $model->myRank; ?>
85 | ... ...
86 | = $ctx->util->fragment('rankline') ?>
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/pages/user/unsolved.php:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 | #
16 | Problem
17 | Language
18 | Link
19 | Date
20 |
21 | records as $record) : ?>
22 |
23 |
24 | = $record->taskid ?>
25 | = $record->title ?>
26 | = $record->language ?>
27 | view
28 | = $record->ts ?>
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/pages/wiki.php:
--------------------------------------------------------------------------------
1 |
13 |
14 | = $model->text ?>
15 |
16 |
= $model->lastmod ?>
17 |
18 |
--------------------------------------------------------------------------------
/pages/wiki/edit.php:
--------------------------------------------------------------------------------
1 |
Wiki edit
2 |
3 |
4 |
5 | Title:
6 |
7 |
8 |
9 | Url:
10 |
11 |
12 |
13 | Text: or "DELETE"
14 | = $model->wikipage->data ?>
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/pages/wiki/index.php:
--------------------------------------------------------------------------------
1 |
Contents
2 |
3 | auth->admin()) : ?>
4 | Add new article
5 |
6 |
7 |
8 | pages as $page) : ?>
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sqlexec.php:
--------------------------------------------------------------------------------
1 | &1", $output, $code);
15 | unlink($tmpname);
16 | echo 'Result: ' . ($code === 0 ? 'OK' : "Fail ($code)") . "\n";
17 | $output = trim(implode("\n", $output));
18 | echo $output ? $output : '(no output)';
19 | return;
20 | }
21 |
22 | ?>
23 |
24 |
25 | MySQL (MariaDB) command executor
26 |
27 |
28 |
29 | Enter some commands, separated by semi-colon. Don't forget start with USE "databasename"
30 | unless you create new database.
31 |
32 |
33 |
34 |
35 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/taskinit.sql:
--------------------------------------------------------------------------------
1 | use ca;
2 |
3 | insert into pfx_tasks (id, title, url, shown) values
4 | (1, 'Simple Sum', 'simple-sum', 1);
5 | insert into pfx_taskdata (taskid, type, data) values
6 | (1, 'text', 'VGhlcmUgYXJlIHR3byByYW5kb20gbnVtYmVycyBwcm92aWRlZCBpbiB0aGUgaW5wdXQsIHBsZWFzZSByZXBvcnQgdGhlaXIgc3VtIGZvciBhbnN3ZXIuCgoqKkV4YW1wbGU6KioKCiAgICBpbnB1dDoKCTE1MyAzNDcKCQoJYW5zd2VyOgoJNTAwCg==');
7 | insert into pfx_taskdata (taskid, type, data) values
8 | (1, 'checker', 'PD9waHAKCmZ1bmN0aW9uIGNoZWNrZXIoKSB7CgkkYSA9IHJhbmQoMTAwLCA5OTkpOwoJJGIgPSByYW5kKDEwMCwgOTk5KTsKICAgIHJldHVybiBhcnJheSgiJGEgJGIiLCAkYSArICRiKTsKfQoKPz4=');
9 |
10 | insert into pfx_tasks (id, title, url, shown) values
11 | (2, 'Sum of Squares', 'sum-of-squares', 1);
12 | insert into pfx_taskdata (taskid, type, data) values
13 | (2, 'text', 'TnVtYmVyIGA4NWAgY291bGQgYmUgcmVwcmVzZW50ZWQgYXMgc3VtIG9mIHR3byBzcXVhcmVzIG9mIHBvc2l0aXZlIGludGVnZXJzIGluIG1vcmUgdGhhbiBvbmUgd2F5OgoKICAgIDg1ICA9ICAyKjIgKyA5KjkgID0gIDYqNiArIDcqNwoKR2l2ZW4gYW4gaW50ZWdlciByYW5nZSBiZXR3ZWVuIGBBYCBhbmQgYEJgIHBsZWFzZSBmaW5kIGhvdyBtYW55IGludGVnZXJzIGluIGl0IGhhdmUgYWxzbyBoYXZlIHN1Y2ggYSBwcm9wZXJ0eS4KCioqRXhhbXBsZToqKgoKCWlucHV0OgoJMzIgMTA5CgkKCWFuc3dlcjoKCTM2NA==');
14 | insert into pfx_taskdata (taskid, type, data) values
15 | (2, 'checker', 'PD9waHAKCmZ1bmN0aW9uIGNoZWNrZXIoKSB7CgkkYSA9IHJhbmQoMTAsIDQwKTsKCSRiID0gJGEgKyByYW5kKDcwLCA4MCk7Cgkkc3VtcyA9IFtdOwoJZm9yICgkeCA9ICRhOyAkeCA8ICRiOyAkeCsrKSB7CgkJZm9yICgkeSA9ICR4KzE7ICR5IDw9ICRiOyAkeSsrKSB7CgkJCSRrID0gJHgqJHggKyAkeSokeTsKCQkJaWYgKCFpc3NldCgkc3Vtc1ska10pKSB7CgkJCQkkc3Vtc1ska10gPSAxOwoJCQl9IGVsc2UgewoJCQkJJHN1bXNbJGtdICs9IDE7CgkJCX0KCQl9Cgl9CgkkY250ID0gMDsKCWZvcmVhY2ggKCRzdW1zIGFzICRrID0+ICR2KSB7CgkJaWYgKCR2ID4gMSkgJGNudCArPSAxOwoJfQogICAgcmV0dXJuIGFycmF5KCIkYSAkYiIsICRjbnQpOwp9Cgo/Pg==');
16 |
17 | insert into pfx_tasktags (taskid, tagid)
18 | select ts.id, tg.id from pfx_tasks ts join pfx_tags tg;
19 |
--------------------------------------------------------------------------------