e33acfcd408cce82cff5680L40">40 46
             <!-- <div [innerHTML]="placelist?.acf.phone"></div>                         -->
@@ -42,29 +48,40 @@
42 48
           </ion-col>
43 49
           <ion-col size="4" class="ion-text-center">
44 50
             <!-- <div [innerHTML]="placelist?.acf.email"></div>             -->
45
-            <fa-icon [icon]="['fas', 'envelope']" size="2x"></fa-icon>
51
+            <div (click)="email2Place('{{placelist?.acf.email}}')">
52
+              <fa-icon [icon]="['fas', 'envelope']" size="2x"></fa-icon>
53
+            </div>
46 54
           </ion-col>
47 55
         </ion-row>
48 56
       </ion-col>
57
+
49 58
       <ion-col size="12">
50
-        <div class="txt-lead">ที่อยู่</div>
51
-        <div [innerHTML]="placelist?.acf.address"></div>
52
-      </ion-col>
53
-      <ion-col size="12">
54
-        <!-- <div class="txt-lead">รายละเอียด</div>
55
-        <div [innerHTML]="placelist?.content.rendered"></div> -->
56
-        <!-- <div>{{placelist?.content.rendered}}</div> -->
57
-        <!-- <ion-button (click)="loadMap()" shape="round" color="dark">
58
-          <ion-icon slot="start" name="locate"></ion-icon>
59
-          Where I Am
60
-        </ion-button> -->
61
-        <div class="map-wrapper">
62
-          <div id="map_center">
63
-            <img src="assets/icon/location-marker.png" />
64
-          </div>
65
-          <div #map id="map"></div>
66
-        </div>
67
-        
59
+        <ion-segment (ionChange)="segmentChanged($event)" value="list1">
60
+          <ion-segment-button value="list1">
61
+            <ion-label>
62
+              ที่อยู่
63
+            </ion-label>
64
+          </ion-segment-button>
65
+          <ion-segment-button value="list2">
66
+            <ion-label>
67
+              รายละเอียด
68
+            </ion-label>
69
+          </ion-segment-button>
70
+        </ion-segment>
71
+
72
+        <ion-list *ngIf="segment === 'list1'">
73
+          <ion-col size="12">
74
+            <!-- <div class="txt-lead">ที่อยู่</div> -->
75
+            <div [innerHTML]="placelist?.acf.address"></div>
76
+          </ion-col>
77
+        </ion-list>
78
+
79
+        <ion-list *ngIf="segment === 'list2'">
80
+          <ion-col size="12">
81
+            <!-- <div class="txt-lead">ที่อยู่</div> -->
82
+            <div [innerHTML]="placelist?.content.rendered"></div>
83
+          </ion-col>
84
+        </ion-list>
68 85
       </ion-col>
69 86
     </ion-row>
70 87
 

+ 0 - 17
src/app/placedetail/placedetail.page.scss

@@ -1,16 +1,3 @@
1
-// ion-toolbar{
2
-//     --background: transparent;
3
-//     --border-color: transparent;
4
-// }
5
-// ion-toolbar{
6
-//     --background: transparent;
7
-//     --border-color: transparent;
8
-// }
9
-// ion-content{
10
-//     --offset-top:0px;
11
-//     position: absolute;
12
-// }
13
-
14 1
 .bg {
15 2
   position: absolute;
16 3
   left: 0px;
@@ -29,10 +16,6 @@
29 16
     --background: white;
30 17
   }
31 18
 }
32
-
33
-.asd {
34
-}
35
-
36 19
 .asd .country {
37 20
   position: absolute;
38 21
   top: 50px;

+ 19 - 19
src/app/placedetail/placedetail.page.ts

@@ -4,6 +4,8 @@ import { WpServiceService } from '../wp-service.service';
4 4
 
5 5
 import { Geolocation } from '@ionic-native/geolocation/ngx';
6 6
 import { NativeGeocoder, NativeGeocoderResult, NativeGeocoderOptions } from '@ionic-native/native-geocoder/ngx';
7
+import { CallNumber } from '@ionic-native/call-number/ngx';
8
+import { EmailComposer } from '@ionic-native/email-composer/ngx';
7 9
 
8 10
 declare var google;
9 11
 
@@ -17,6 +19,8 @@ export class PlacedetailPage implements OnInit {
17 19
   data: any;
18 20
   placelist: any;
19 21
 
22
+  public segment: string = "list1";
23
+
20 24
   @ViewChild('map', { static: false }) mapElement: ElementRef;
21 25
   map: any;
22 26
   address: string;
@@ -24,9 +28,9 @@ export class PlacedetailPage implements OnInit {
24 28
   longitude: number;
25 29
   latdynamic: any;
26 30
   londynamic: any;
27
-  
28 31
 
29
-  constructor(private wpservice: WpServiceService, private route: ActivatedRoute, private router: Router, private geolocation: Geolocation, private nativeGeocoder: NativeGeocoder) { }
32
+
33
+  constructor(private wpservice: WpServiceService, private route: ActivatedRoute, private router: Router, private geolocation: Geolocation, private nativeGeocoder: NativeGeocoder,private callNumber: CallNumber, private emailComposer: EmailComposer) { }
30 34
   @Input() id: string;
31 35
   showDiss = false;
32 36
 
@@ -121,21 +125,17 @@ export class PlacedetailPage implements OnInit {
121 125
 
122 126
   }
123 127
 
124
-  // getAddressFromCoords2(lattitude, longitude) {
125
-  //   console.log("getAddressFromCoords2 " + lattitude + " " + longitude);
126
-  //   let options: NativeGeocoderOptions = {
127
-  //     useLocale: true,
128
-  //     maxResults: 5
129
-  //   };
130
-  // }
131
-
132
-  // getGeoencoder(latitude, longitude) {
133
-  //   this.nativeGeocoder.reverseGeocode(latitude, longitude, this.geoencoderOptions)
134
-  //     .then((result: NativeGeocoderResult[]) => {
135
-  //       this.address = this.generateAddress(result[0]);
136
-  //     })
137
-  //     .catch((error: any) => {
138
-  //       alert('Error getting location' + JSON.stringify(error));
139
-  //     });
140
-  // }
128
+  segmentChanged(ev: any) {
129
+    this.segment = ev.detail.value;
130
+  }
131
+
132
+  callNow(number) {
133
+    this.callNumber.callNumber(number, true)
134
+      .then(res => console.log('Launched dialer!', res))
135
+      .catch(err => console.log('Error launching dialer', err));
136
+  }
137
+
138
+  email2Place(mail) {
139
+    this.emailComposer.open(mail)
140
+  }
141 141
 }

+ 18 - 11
src/app/profile/profile.page.html

@@ -1,10 +1,14 @@
1 1
 <ion-header>
2
-  <ion-toolbar>
2
+  <ion-toolbar class="new-background-color">
3
+    <ion-buttons slot="start" color="light">
4
+      <ion-back-button></ion-back-button>
5
+    </ion-buttons>
3 6
     <ion-title>Wellness Route</ion-title>
4 7
   </ion-toolbar>
5 8
 </ion-header>
6
-<ion-content fullscreen="true">
7
-  <!-- <div *ngIf="(user2 | async) as user; else loading"> -->
9
+<ion-content>
10
+  <ion-grid>
11
+    <!-- <div *ngIf="(user2 | async) as user; else loading"> -->
8 12
     <ion-row>
9 13
       <ion-col>
10 14
         <div class="ion-text-center">
@@ -17,32 +21,35 @@
17 21
         <div class="card">
18 22
           <div class="header">
19 23
             <div class="avatar">
20
-              <img [src]="$any(user).picture_large.data.url" *ngIf="user['picture_large'] != undefined" />
21
-              <img src="/assets/images/icon-user.png" *ngIf="user['picture_large'] == undefined" />
24
+              <!-- <img [src]="$any(user).picture_large.data.url" *ngIf="user['picture_large'] != undefined" /> -->
25
+              <!-- <img src="/assets/images/icon-user.png" *ngIf="user['picture_large'] == undefined" /> -->
26
+              <img src="/assets/images/icon-user.png">
22 27
             </div>
23 28
           </div>
24 29
         </div>
25 30
         <div class="card-body">
26 31
           <div class="user-meta ion-text-center">
27
-            <h3 class="playername">{{ $any(user).name }}</h3>
32
+            <!-- <h3 class="playername">{{ $any(user).name }}</h3> -->
28 33
           </div>
29 34
           <form>
30 35
             <ion-item lines="full">
31 36
               <ion-label>ชื่อ</ion-label>
32
-              {{ $any(user).name }}
37
+              <!-- {{ $any(user).name }} -->
33 38
             </ion-item>
34 39
             <ion-item lines="full">
35
-              <ion-label>Email</ion-label>{{ $any(user).email }}
40
+              <ion-label>อีเมล์</ion-label>
41
+              <!-- {{ $any(user).email }} -->
36 42
             </ion-item>
37 43
             <div class="ion-padding-vertical">
38
-              <ion-button type="submit" color="danger" expand="block" (click)="logout()">Log Out</ion-button>
44
+              <!-- <ion-button type="submit" color="danger" expand="block" (click)="logout()">Log Out</ion-button> -->
39 45
             </div>
40 46
           </form>
41 47
         </div>
42 48
       </ion-col>
43 49
     </ion-row>
44
-  <!-- </div> -->
45
-  <!-- <ng-template #loading>
50
+    <!-- </div> -->
51
+    <!-- <ng-template #loading>
46 52
     Loading stuff...
47 53
   </ng-template> -->
54
+  </ion-grid>
48 55
 </ion-content>

+ 1 - 0
src/app/profile/profile.page.ts

@@ -8,6 +8,7 @@ import { Component, OnInit } from '@angular/core';
8 8
 export class ProfilePage implements OnInit {
9 9
 
10 10
   user2: any;
11
+  user: any;
11 12
   
12 13
   constructor() { }
13 14
 

+ 28 - 29
src/app/province/province.page.html

@@ -6,34 +6,33 @@
6 6
     <ion-title>Wellnewss Route</ion-title>
7 7
   </ion-toolbar>
8 8
 </ion-header>
9
-
10 9
 <ion-content>
11
-  <img src="/assets/images/welcome_drone.jpeg" alt="">
12
-  <div class="holidaycard">
13
-    <ion-grid>
14
-      <ion-row>
15
-        <ion-col size="12">
16
-          <div class="txt-place-title">Province Name</div>
17
-        </ion-col>
18
-      </ion-row>
19
-      <ion-row>
20
-        <ion-col>
21
-          <ion-toolbar class="search">
22
-            <ion-searchbar placeholder="ค้นหา"></ion-searchbar>
23
-          </ion-toolbar>
24
-        </ion-col>
25
-      </ion-row>
26
-      <ion-card *ngFor="let provlist of provicelist">
27
-        <div *ngIf="$any(provlist).better_featured_image != null">
28
-          <img src="{{$any(provlist).better_featured_image.source_url}}" alt="">
29
-        </div>
30
-        <div *ngIf="$any(provlist).better_featured_image == null">
31
-          <img src="/assets/images/temp.png" />
32
-        </div>
33
-        <ion-card-header>
34
-          <a [routerLink]="['/tabs/place/', provlist.id]"><ion-card-title [innerHTML]="provlist.title.rendered"></ion-card-title></a>
35
-        </ion-card-header>
36
-      </ion-card>
37
-    </ion-grid>
38
-  </div>
10
+  <img src="/assets/images/image-004.jpg" alt="">
11
+  <ion-grid>
12
+    <ion-row>
13
+      <ion-col size="12">
14
+        <div class="txt-place-title">Province Name</div>
15
+      </ion-col>
16
+    </ion-row>
17
+    <ion-row>
18
+      <ion-col>
19
+        <ion-toolbar class="search">
20
+          <ion-searchbar placeholder="ค้นหา"></ion-searchbar>
21
+        </ion-toolbar>
22
+      </ion-col>
23
+    </ion-row>
24
+    <ion-card *ngFor="let provlist of provicelist">
25
+      <div *ngIf="$any(provlist).better_featured_image != null">
26
+        <img src="{{$any(provlist).better_featured_image.source_url}}" alt="">
27
+      </div>
28
+      <div *ngIf="$any(provlist).better_featured_image == null">
29
+        <img src="/assets/images/temp.png" />
30
+      </div>
31
+      <ion-card-header>
32
+        <a [routerLink]="['/tabs/place/', provlist.id]">
33
+          <ion-card-title [innerHTML]="provlist.title.rendered"></ion-card-title>
34
+        </a>
35
+      </ion-card-header>
36
+    </ion-card>
37
+  </ion-grid>
39 38
 </ion-content>

+ 12 - 12
src/app/province/province.page.scss

@@ -1,16 +1,16 @@
1 1
 
2
-.holidaycard {
3
-  position: absolute;
4
-  left: 0px;
5
-  // bottom: 0px;
6
-  top:200px;
7
-  min-height: 48%;
8
-  width: 100%;
9
-  padding: 5px;
10
-  border-radius: 15px ;
11
-  background: white;
12
-  --background: white;
13
-}
2
+// .holidaycard {
3
+//   position: absolute;
4
+//   left: 0px;
5
+//   // bottom: 0px;
6
+//   top:200px;
7
+//   min-height: 48%;
8
+//   width: 100%;
9
+//   padding: 5px;
10
+//   border-radius: 15px ;
11
+//   background: white;
12
+//   --background: white;
13
+// }
14 14
 
15 15
 ion-card-title {
16 16
   font-family: "IBM Plex Sans Thai", sans-serif !important;

+ 10 - 7
src/app/register-form/register-form.page.html

@@ -1,10 +1,13 @@
1 1
 <ion-header>
2
-  <ion-toolbar>
2
+  <ion-toolbar class="new-background-color">
3
+    <ion-buttons slot="start" color="light">
4
+      <ion-back-button></ion-back-button>
5
+    </ion-buttons>
3 6
     <ion-title>Wellness Route</ion-title>
4 7
   </ion-toolbar>
5 8
 </ion-header>
6
-
7 9
 <ion-content>
10
+  <div><img src="/assets/images/image-001.jpg"></div>
8 11
   <ion-row>
9 12
     <ion-col>
10 13
       <div class="ion-text-center">
@@ -13,9 +16,9 @@
13 16
     </ion-col>
14 17
   </ion-row>
15 18
   <ion-row>
16
-    <ion-col>      
19
+    <ion-col>
17 20
       <form>
18
-        <ion-text *ngIf="errorText" color="primary" style='background-color:#fff'>
21
+        <ion-text *ngIf="errorText" color="primary">
19 22
           {{ errorText }}
20 23
         </ion-text>
21 24
         <ion-item lines="full">
@@ -45,9 +48,9 @@
45 48
         </ion-item>
46 49
 
47 50
         <div class="ion-padding-vertical">
48
-          <ion-button type="submit" color="success" expand="block" (click)="register()">ลงทะเบียน</ion-button>
51
+          <ion-button type="submit" color="success" expand="block">ลงทะเบียน</ion-button>
49 52
         </div>
50 53
       </form>
51 54
     </ion-col>
52
-  </ion-row>  
53
-</ion-content>
55
+  </ion-row>
56
+</ion-content>

+ 10 - 7
src/app/register/register.page.html

@@ -1,20 +1,23 @@
1 1
 <ion-header>
2
-  <ion-toolbar>
3
-    <ion-title>ลงทะเบียน</ion-title>
2
+  <ion-toolbar class="new-background-color">
3
+    <ion-buttons slot="start" color="light">
4
+      <ion-back-button></ion-back-button>
5
+    </ion-buttons>
6
+    <ion-title>Wellness Route</ion-title>
4 7
   </ion-toolbar>
5 8
 </ion-header>
6
-
7 9
 <ion-content class="auth-form">
10
+  <div><img src="/assets/images/image-001.jpg"></div>
8 11
   <ion-grid>
9 12
     <ion-row>
10 13
       <ion-col align-self-center>
11
-        <ion-button [routerLink]="['/registration']" expand="block" color="primary">Register</ion-button>
14
+        <ion-button [routerLink]="['/register-form']" expand="block" color="primary">ลงทะเบียนผู้ใช้งาน</ion-button>
12 15
 
13
-        <span class="divider line one-line">or</span>
16
+        <span class="divider line one-line">หรือ</span>
14 17
 
15
-        <span class="already">Already a user?</span>
18
+        <span class="already">มีชื่อผู้ใช้งานแล้ว</span>
16 19
 
17
-        <ion-button [routerLink]="['/login']" expand="block" color="danger">Sign In</ion-button>
20
+        <ion-button [routerLink]="['/login']" expand="block" color="danger">เข้าสู่ระบบ</ion-button>
18 21
       </ion-col>
19 22
     </ion-row>
20 23
   </ion-grid>

+ 2 - 2
src/app/register/register.page.scss

@@ -12,7 +12,7 @@
12 12
   .line {
13 13
     align-items: center;
14 14
     margin: 1em -1em;
15
-    color: #cccccc;
15
+    color: #5f5e5e;
16 16
     
17 17
     &:before,
18 18
     &:after {
@@ -24,7 +24,7 @@
24 24
   .one-line {
25 25
     &:before,
26 26
     &:after {
27
-       background: #cccccc;
27
+       background: #5f5e5e;
28 28
     }
29 29
   }
30 30
   

+ 29 - 24
src/app/reset-password/reset-password.page.html

@@ -1,33 +1,38 @@
1 1
 <ion-header>
2
-  <ion-toolbar>
2
+  <ion-toolbar class="new-background-color">
3
+    <ion-buttons slot="start" color="light">
4
+      <ion-back-button></ion-back-button>
5
+    </ion-buttons>
3 6
     <ion-title>Wellness Route</ion-title>
4 7
   </ion-toolbar>
5 8
 </ion-header>
6
-
7 9
 <ion-content>
8
-  <ion-row>
9
-    <ion-col class="ion-text-center">
10
-      <h1>กรุณาใส่รหัสผ่านใหม่</h1>
11
-    </ion-col>
12
-  </ion-row>
13
-  <form>
14
-    <ion-row>
15
-      <ion-col>
16
-        <ion-item lines="full">
17
-          <ion-label position="floating">รหัสผ่าน</ion-label>
18
-          <ion-input type="password" required></ion-input>
19
-        </ion-item>
20
-
21
-        <ion-item lines="full">
22
-          <ion-label position="floating">ยืนยัน รหัสผ่าน</ion-label>
23
-          <ion-input type="password" required></ion-input>
24
-        </ion-item>
25
-      </ion-col>
26
-    </ion-row>
10
+  <div><img src="/assets/images/image-007.jpg"></div>
11
+  <ion-grid>
27 12
     <ion-row>
28
-      <ion-col>
29
-        <ion-button type="submit" color="success" expand="block">ส่ง</ion-button>
13
+      <ion-col class="ion-text-center">
14
+        <h1>กรุณาใส่รหัสผ่านใหม่</h1>
30 15
       </ion-col>
31 16
     </ion-row>
32
-  </form>
17
+    <form>
18
+      <ion-row>
19
+        <ion-col>
20
+          <ion-item lines="full">
21
+            <ion-label position="floating">รหัสผ่าน</ion-label>
22
+            <ion-input type="password" required></ion-input>
23
+          </ion-item>
24
+
25
+          <ion-item lines="full">
26
+            <ion-label position="floating">ยืนยัน รหัสผ่าน</ion-label>
27
+            <ion-input type="password" required></ion-input>
28
+          </ion-item>
29
+        </ion-col>
30
+      </ion-row>
31
+      <ion-row>
32
+        <ion-col>
33
+          <ion-button type="submit" color="success" expand="block">ส่ง</ion-button>
34
+        </ion-col>
35
+      </ion-row>
36
+    </form>
37
+  </ion-grid>
33 38
 </ion-content>

+ 2 - 2
src/app/tabs/tabs.page.html

@@ -1,9 +1,9 @@
1 1
 <ion-tabs>
2
-  <ion-fab vertical="bottom" horizontal="center" translucent="true">
2
+  <!-- <ion-fab vertical="bottom" horizontal="center" translucent="true">
3 3
     <ion-fab-button routerLink="nearme" routerDirection="forward">
4 4
     <ion-icon name="navigate"></ion-icon>
5 5
     </ion-fab-button>
6
-  </ion-fab>
6
+  </ion-fab> -->
7 7
   <ion-tab-bar slot="bottom">
8 8
     <ion-tab-button tab="home">
9 9
       <ion-icon name="home"></ion-icon>

+ 2 - 1
src/app/wp-service.service.ts

@@ -31,7 +31,8 @@ export class WpServiceService {
31 31
 
32 32
   getPlaceDetail(id) {
33 33
     return this.http.get(
34
-      "http://tamtime.iamarray.xyz/wp-json/wp/v2/place/"+id+"/?_embed"
34
+      // "http://tamtime.iamarray.xyz/wp-json/wp/v2/place/"+id+"/?_embed"
35
+      "/assets/json/place173.json"
35 36
     );
36 37
   }
37 38
 

二进制
src/assets/images/image-001.jpg


二进制
src/assets/images/image-002.jpg


二进制
src/assets/images/image-003.jpg


二进制
src/assets/images/image-004.jpg


二进制
src/assets/images/image-005.jpg


二进制
src/assets/images/image-006.jpg


二进制
src/assets/images/image-007.jpg


二进制
src/assets/images/image-008.jpg


二进制
src/assets/images/image-009.jpg


二进制
src/assets/images/image-010.jpg


二进制
src/assets/images/image-011.jpg


二进制
src/assets/images/image-012.jpg


文件差异内容过多而无法显示
+ 1 - 0
src/assets/json/place173.json


+ 18 - 7
src/global.scss

@@ -116,6 +116,17 @@
116 116
   --color: #ffffff;
117 117
 }
118 118
 
119
+// ion-content {
120
+//   --background: linear-gradient(
121
+//     to bottom,
122
+//     #a7e9ff,
123
+//     #8fd8fd,
124
+//     #7ec7fb,
125
+//     #78b4f6,
126
+//     #7c9fee
127
+//   );
128
+// }
129
+
119 130
 ion-title {
120 131
   font-family: "Kanit", sans-serif !important;
121 132
   font-weight: 500;
@@ -160,12 +171,12 @@ ion-button {
160 171
 
161 172
 a {
162 173
   text-decoration: none;
163
- }
164
- 
165
-// ion-content {
166
-//   --background: url(/assets/images/wnr-bg.jpg) no-repeat center/cover fixed;
167
-// }
174
+}
175
+
176
+.image-page-cover {
177
+  height: 200px;
178
+}
168 179
 .ios ion-fab-button {
169
-  position:absolute;
180
+  position: absolute;
170 181
   bottom: 25px;
171
-}
182
+}

tum/whitesports - Gogs: Simplico Git Service

Nav apraksta

theme-install.php 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. /**
  3. * WordPress Theme Installation Administration API
  4. *
  5. * @package WordPress
  6. * @subpackage Administration
  7. */
  8. $themes_allowedtags = array(
  9. 'a' => array(
  10. 'href' => array(),
  11. 'title' => array(),
  12. 'target' => array(),
  13. ),
  14. 'abbr' => array( 'title' => array() ),
  15. 'acronym' => array( 'title' => array() ),
  16. 'code' => array(),
  17. 'pre' => array(),
  18. 'em' => array(),
  19. 'strong' => array(),
  20. 'div' => array(),
  21. 'p' => array(),
  22. 'ul' => array(),
  23. 'ol' => array(),
  24. 'li' => array(),
  25. 'h1' => array(),
  26. 'h2' => array(),
  27. 'h3' => array(),
  28. 'h4' => array(),
  29. 'h5' => array(),
  30. 'h6' => array(),
  31. 'img' => array(
  32. 'src' => array(),
  33. 'class' => array(),
  34. 'alt' => array(),
  35. ),
  36. );
  37. $theme_field_defaults = array(
  38. 'description' => true,
  39. 'sections' => false,
  40. 'tested' => true,
  41. 'requires' => true,
  42. 'rating' => true,
  43. 'downloaded' => true,
  44. 'downloadlink' => true,
  45. 'last_updated' => true,
  46. 'homepage' => true,
  47. 'tags' => true,
  48. 'num_ratings' => true,
  49. );
  50. /**
  51. * Retrieve list of WordPress theme features (aka theme tags).
  52. *
  53. * @since 2.8.0
  54. *
  55. * @deprecated 3.1.0 Use get_theme_feature_list() instead.
  56. *
  57. * @return array
  58. */
  59. function install_themes_feature_list() {
  60. _deprecated_function( __FUNCTION__, '3.1.0', 'get_theme_feature_list()' );
  61. $cache = get_transient( 'wporg_theme_feature_list' );
  62. if ( ! $cache ) {
  63. set_transient( 'wporg_theme_feature_list', array(), 3 * HOUR_IN_SECONDS );
  64. }
  65. if ( $cache ) {
  66. return $cache;
  67. }
  68. $feature_list = themes_api( 'feature_list', array() );
  69. if ( is_wp_error( $feature_list ) ) {
  70. return array();
  71. }
  72. set_transient( 'wporg_theme_feature_list', $feature_list, 3 * HOUR_IN_SECONDS );
  73. return $feature_list;
  74. }
  75. /**
  76. * Display search form for searching themes.
  77. *
  78. * @since 2.8.0
  79. *
  80. * @param bool $type_selector
  81. */
  82. function install_theme_search_form( $type_selector = true ) {
  83. $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
  84. $term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
  85. if ( ! $type_selector ) {
  86. echo '<p class="install-help">' . __( 'Search for themes by keyword.' ) . '</p>';
  87. }
  88. ?>
  89. <form id="search-themes" method="get">
  90. <input type="hidden" name="tab" value="search" />
  91. <?php if ( $type_selector ) : ?>
  92. <label class="screen-reader-text" for="typeselector"><?php _e( 'Type of search' ); ?></label>
  93. <select name="type" id="typeselector">
  94. <option value="term" <?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
  95. <option value="author" <?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
  96. <option value="tag" <?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Theme Installer' ); ?></option>
  97. </select>
  98. <label class="screen-reader-text" for="s">
  99. <?php
  100. switch ( $type ) {
  101. case 'term':
  102. _e( 'Search by keyword' );
  103. break;
  104. case 'author':
  105. _e( 'Search by author' );
  106. break;
  107. case 'tag':
  108. _e( 'Search by tag' );
  109. break;
  110. }
  111. ?>
  112. </label>
  113. <?php else : ?>
  114. <label class="screen-reader-text" for="s"><?php _e( 'Search by keyword' ); ?></label>
  115. <?php endif; ?>
  116. <input type="search" name="s" id="s" size="30" value="<?php echo esc_attr( $term ); ?>" autofocus="autofocus" />
  117. <?php submit_button( __( 'Search' ), '', 'search', false ); ?>
  118. </form>
  119. <?php
  120. }
  121. /**
  122. * Display tags filter for themes.
  123. *
  124. * @since 2.8.0
  125. */
  126. function install_themes_dashboard() {
  127. install_theme_search_form( false );
  128. ?>
  129. <h4><?php _e( 'Feature Filter' ); ?></h4>
  130. <p class="install-help"><?php _e( 'Find a theme based on specific features.' ); ?></p>
  131. <form method="get">
  132. <input type="hidden" name="tab" value="search" />
  133. <?php
  134. $feature_list = get_theme_feature_list();
  135. echo '<div class="feature-filter">';
  136. foreach ( (array) $feature_list as $feature_name => $features ) {
  137. $feature_name = esc_html( $feature_name );
  138. echo '<div class="feature-name">' . $feature_name . '</div>';
  139. echo '<ol class="feature-group">';
  140. foreach ( $features as $feature => $feature_name ) {
  141. $feature_name = esc_html( $feature_name );
  142. $feature = esc_attr( $feature );
  143. ?>
  144. <li>
  145. <input type="checkbox" name="features[]" id="feature-id-<?php echo $feature; ?>" value="<?php echo $feature; ?>" />
  146. <label for="feature-id-<?php echo $feature; ?>"><?php echo $feature_name; ?></label>
  147. </li>
  148. <?php } ?>
  149. </ol>
  150. <br class="clear" />
  151. <?php
  152. }
  153. ?>
  154. </div>
  155. <br class="clear" />
  156. <?php submit_button( __( 'Find Themes' ), '', 'search' ); ?>
  157. </form>
  158. <?php
  159. }
  160. /**
  161. * @since 2.8.0
  162. */
  163. function install_themes_upload() {
  164. ?>
  165. <p class="install-help"><?php _e( 'If you have a theme in a .zip format, you may install or update it by uploading it here.' ); ?></p>
  166. <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-theme' ); ?>">
  167. <?php wp_nonce_field( 'theme-upload' ); ?>
  168. <label class="screen-reader-text" for="themezip"><?php _e( 'Theme zip file' ); ?></label>
  169. <input type="file" id="themezip" name="themezip" accept=".zip" />
  170. <?php submit_button( __( 'Install Now' ), '', 'install-theme-submit', false ); ?>
  171. </form>
  172. <?php
  173. }
  174. /**
  175. * Prints a theme on the Install Themes pages.
  176. *
  177. * @deprecated 3.4.0
  178. *
  179. * @global WP_Theme_Install_List_Table $wp_list_table
  180. *
  181. * @param object $theme
  182. */
  183. function display_theme( $theme ) {
  184. _deprecated_function( __FUNCTION__, '3.4.0' );
  185. global $wp_list_table;
  186. if ( ! isset( $wp_list_table ) ) {
  187. $wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
  188. }
  189. $wp_list_table->prepare_items();
  190. $wp_list_table->single_row( $theme );
  191. }
  192. /**
  193. * Display theme content based on theme list.
  194. *
  195. * @since 2.8.0
  196. *
  197. * @global WP_Theme_Install_List_Table $wp_list_table
  198. */
  199. function display_themes() {
  200. global $wp_list_table;
  201. if ( ! isset( $wp_list_table ) ) {
  202. $wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
  203. }
  204. $wp_list_table->prepare_items();
  205. $wp_list_table->display();
  206. }
  207. /**
  208. * Display theme information in dialog box form.
  209. *
  210. * @since 2.8.0
  211. *
  212. * @global WP_Theme_Install_List_Table $wp_list_table
  213. */
  214. function install_theme_information() {
  215. global $wp_list_table;
  216. $theme = themes_api( 'theme_information', array( 'slug' => wp_unslash( $_REQUEST['theme'] ) ) );
  217. if ( is_wp_error( $theme ) ) {
  218. wp_die( $theme );
  219. }
  220. iframe_header( __( 'Theme Installation' ) );
  221. if ( ! isset( $wp_list_table ) ) {
  222. $wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
  223. }
  224. $wp_list_table->theme_installer_single( $theme );
  225. iframe_footer();
  226. exit;
  227. }